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

898 lines
No EOL
78 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

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>10.9. Files &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="1. Glossary" href="Glossary.html" />
<link rel="prev" title="8. Function Pointers" href="FunctionPointers.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="Files.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="Files.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/Files.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="FunctionPointers.html">10.8. Function Pointers</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="Glossary.html">11.1. Glossary</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 = "Files";ODSA.SETTINGS.MODULE_LONG_NAME = "Files";ODSA.SETTINGS.MODULE_CHAPTER = "Appendix A"; ODSA.SETTINGS.BUILD_DATE = "2021-06-14 17:15:26"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="id1">
<h1>10.9. Files<a class="headerlink" href="Files.html#id1" title="Permalink to this headline"></a></h1>
<p>The idea of organizing and storing data as a file is one of the oldest abstractions in computing,
with references to files dating back to the earliest computers in the 1940s. From the perspective of
C and the UNIX OS tradition, a file is just a sequence of bytes. Chapter 2 explores the implications
of this definition in further detail, such as the fact that not all files exist on persistent
storage devices and not all files have names. In this Appendix, for simplicity, we will adopt the
conventional interpretation of a file stored on a device, such as a hard drive or a USB-attached device.</p>
<div class="section" id="file-permissions-and-ownership">
<h2>10.9.1. File Permissions and Ownership<a class="headerlink" href="Files.html#file-permissions-and-ownership" title="Permalink to this headline"></a></h2>
<p>When a file is stored, there is a certain amount of information—called <a class="reference internal" href="Glossary.html#term-metadata"><span class="xref std std-term">metadata</span></a>—that is
stored alongside the files contents. Metadata is stored in a data structure called an
<a class="reference internal" href="Glossary.html#term-inode"><span class="xref std std-term">inode</span></a>, as discussed in Chapter 2. The inode contains a number of fields, one of which is the
files permission mode. The permission mode indicates which actions (read, write, or execute) can be
performed on a file by a particular user. These permission modes are commonly written as three octal
values to specify permissions for the user (the owner of the file), the group (a pre-defined set of
users), or others (everyone else). For each octal value, 4 (binary 100) indicates read permission, 2
(010) is write, and 1 (001) is execute. Setting one of these bits to 0 removes that permission.</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</span> <span class="pre">chmod(const</span> <span class="pre">char</span> <span class="pre">*path,</span> <span class="pre">mode_t</span> <span class="pre">mode);</span></code></dt>
<dd>Change the permissions associated with a file.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">fchmod(int</span> <span class="pre">fildes,</span> <span class="pre">mode_t</span> <span class="pre">mode);</span></code></dt>
<dd>Change the permissions associated with an open file given its file descriptor.</dd>
</dl>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">chmod()</span></code> and <code class="docutils literal notranslate"><span class="pre">fchmod()</span></code> functions, which can only be used by the owner of a particular
file, provide an interface to change the permissions on a file. The first argument specifies which
file, either by the standard file name (<code class="docutils literal notranslate"><span class="pre">path</span></code>) or using a file descriptor (<code class="docutils literal notranslate"><span class="pre">filedes</span></code>). The mode
argument is the new permission bit mask to apply. Although the <code class="docutils literal notranslate"><span class="pre">mode_t</span></code> type is just an integer
(e.g., 493), these numbers are written in their octal equivalent (<code class="docutils literal notranslate"><span class="pre">0755</span></code>). (The leading 0 is
required to indicate octal format.) Among the three digits, the first applies to the user, the
second to the group, and the third to others.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-58"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.58:</span>
<span class="cm"> Changing two files&#39; permissions within a program</span>
<span class="cm"> */</span>
<span class="cm">/* Everyone has read access, user also has write */</span>
<span class="n">chmod</span> <span class="p">(</span><span class="s">&quot;data.txt&quot;</span><span class="p">,</span> <span class="mo">0644</span><span class="p">);</span>
<span class="cm">/* User and group can execute the Python script, and the user can</span>
<span class="cm"> modify (write) it; others have no access */</span>
<span class="n">chmod</span> <span class="p">(</span><span class="s">&quot;script.py&quot;</span><span class="p">,</span> <span class="mo">0750</span><span class="p">);</span>
<span class="cm">/* Restrict access to a private directory */</span>
<span class="n">chmod</span> <span class="p">(</span><span class="s">&quot;/home/csf/private_files&quot;</span><span class="p">,</span> <span class="mo">0700</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="Files.html#cla-58">Code Listing A.58</a> changes the permissions on three files using the <code class="docutils literal notranslate"><span class="pre">chmod()</span></code>
function. The bit mask on line 6 (<code class="docutils literal notranslate"><span class="pre">0644</span></code>) indicates that the user will have read and write
permission (applying the bit-wise OR operator, <code class="docutils literal notranslate"><span class="pre">4</span> <span class="pre">|</span> <span class="pre">2</span> <span class="pre">=</span> <span class="pre">6</span></code>), while the group and other have only
read permission. Line 10 gives the user all permissions (<code class="docutils literal notranslate"><span class="pre">4</span> <span class="pre">|</span> <span class="pre">2</span> <span class="pre">|</span> <span class="pre">1</span> <span class="pre">=</span> <span class="pre">7</span></code>, meaning read, write, and
execute), whereas the group only has read and execute (<code class="docutils literal notranslate"><span class="pre">4</span> <span class="pre">|</span> <span class="pre">1</span> <span class="pre">=</span> <span class="pre">5</span></code>). Line 13 changes the
permission on a <em>directory</em>—a special file that “contains” other files (explained below).
Directories in the UNIX tradition are the equivalent of <em>folders</em> in the Windows family of operating
systems. The permissions here give the user full access to the directory, but the group and others
are blocked out. These operations can also be performed on the command line as follows (note that
the <code class="docutils literal notranslate"><span class="pre">chmod</span></code> utility is a C program that calls <code class="docutils literal notranslate"><span class="pre">chmod()</span></code> internally!). The <code class="docutils literal notranslate"><span class="pre">ls</span> <span class="pre">-ld</span></code> command
displays the permissions at the first part of the file, in a format <code class="docutils literal notranslate"><span class="pre">rwxrwxrwx</span></code> for the three
octal values (<code class="docutils literal notranslate"><span class="pre">-</span></code> indicates that permission is not set).</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>$ chmod 644 data.txt
$ chmod 750 script.py
$ chmod 700 /home/csf/private_files
$ ls -ld data.txt script.py /home/csf/private
-rw-r--r-- 1 csf staff 8528 Jul 31 23:20 data.txt
-rwxr-x--- 1 csf staff 440 Jul 31 23:20 script.py
drwx------ 11 csf staff 352 Jul 31 23:20 /home/csf/private
</pre></div>
</div>
<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-Note.png"><img alt="Decorative note icon" src="_images/CSF-Images-Note.png" style="width: 100%;" /></a>
</div>
<p class="topic-title first pt-2 mb-1">Note</p><hr class="mt-1" />
<p>The permission bits—particularly read and execute—are not as intuitive as their names suggest. For
instance, why is the read bit required to run the script.py Python script? As a piece of code, the
goal is to run—i.e., execute—it. Similarly, what does it mean to “execute” a directory? The
interpretation of these bits requires considering the type of file in a greater context.</p>
<p>For normal files (i.e., non-directories), the read bit indicates that a running process can open the
file and copy its contents into memory. In the case of scripting languages like Python, it is
important to understand that the process that is running is not executing the <code class="docutils literal notranslate"><span class="pre">script.py</span></code> code.
It cant, because to “execute” code means that the CPU is performing machine-language instructions;
Python code is not machine language, because it is not compiled. Rather, the process is running the
Python interpreter (typically stored in a location like <code class="docutils literal notranslate"><span class="pre">/usr/bin/python</span></code>). The read permission
bit gives the Python interpreter access to read in <code class="docutils literal notranslate"><span class="pre">script.py</span></code> as text data. The interpreter then
simulates the execution of the program. For performance reasons, the interpreter might compile
parts of the script into machine language using <em>just-in-time compilation</em>, but that is not
necessary.</p>
<p>So if Python only needs to read the file, what is the purpose of setting the execute bit on
<code class="docutils literal notranslate"><span class="pre">script.py</span></code>? In truth—and somewhat ironically—the execute bit does not indicate that
<code class="docutils literal notranslate"><span class="pre">script.py</span></code> can be executed. The execute bit on files declares that the file should be found as
an executable within the <code class="docutils literal notranslate"><span class="pre">$PATH</span></code> environment variable—a list of locations to search for
executables—that the shell (<code class="docutils literal notranslate"><span class="pre">bash</span></code>) uses. When you type a command, <code class="docutils literal notranslate"><span class="pre">bash</span></code> searches through the
locations listed in the <code class="docutils literal notranslate"><span class="pre">$PATH</span></code> for the first match of that command name that has the execute bit
set. To start the process, <code class="docutils literal notranslate"><span class="pre">bash</span></code> looks into the file contents to look at the first line of the
program. In the case of scripts like <code class="docutils literal notranslate"><span class="pre">script.py</span></code>, the first line contains a <em>shebang</em> operator
that indicates the location of the interpreter that is needed:</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>#!/usr/bin/python
</pre></div>
</div>
<p>Consequently, executing a Python script requires the execute bit to add it to the <code class="docutils literal notranslate"><span class="pre">$PATH</span></code> that is
searched, but requires the read bit for the program to actually run.</p>
<p>The execute bit on directories is also frequently misunderstood, primarily because the bit is
misnamed for directories. A directory is not a piece of code that can be run (executed). Instead,
reading a directory is defined as listing its contents, whereas the execute bit allows the user to
<em>enter or pass through</em> the directory. For instance, consider the following file name (storing a
cryptographic key that can be used to log into a remote email service), based on the permissions above:</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>/home/csf/private/keys/email.id_rsa
</pre></div>
</div>
<p><a class="reference external" href="Files.html#cla-58">Code Listing A.58</a> set <code class="docutils literal notranslate"><span class="pre">0700</span></code> permissions for the <code class="docutils literal notranslate"><span class="pre">/home/csf/private</span></code>. The read bit
allows the user to list the file contents (using the <code class="docutils literal notranslate"><span class="pre">ls</span></code> command, for instance). However,
accessing those files or the subdirectories requires the execute bit. Since the group and others
have no permissions, no one else can get access to the <code class="docutils literal notranslate"><span class="pre">keys</span></code> subdirectory, because doing so
requires passing through <code class="docutils literal notranslate"><span class="pre">private</span></code>. Since the read and execute actions are distinct, the bits can
be set independently. Setting a directory to <code class="docutils literal notranslate"><span class="pre">0444</span></code> would allow everyone to see the names of
files in the directory, but no one could access any of them or access any subdirectories. On the
other hand, setting the directory to <code class="docutils literal notranslate"><span class="pre">0111</span></code> would give everyone access to the files and
subdirectories…if they already knew the name; these permissions would not allow anyone to list
the directory contents to see the names of the files.</p>
<p>For completeness, writing to a directory means adding or removing files. When you save a new file
into a directory, you are writing to the directory by adding an entry. When you delete a file, you
are also writing by removing the entry. It is important to note that these operations are changes
to the directory, not the file itself. To be precise, this means that <strong>you do not have to own a
file in order to delete it</strong>. When you are deleting a file, you are not writing to it; you are
writing to the directory. As such, if you have data that is important and should never be deleted,
you should not place it in a directory that others can write to.</p>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">access()</span></code> function provides an interface to check a files permissions before trying to
access it. As with the <code class="docutils literal notranslate"><span class="pre">chmod()</span></code> function, the first parameter specifies the name of the file
being checked. The <code class="docutils literal notranslate"><span class="pre">mode</span></code> parameter is not the same as the <code class="docutils literal notranslate"><span class="pre">mode_t</span></code> type used above, because
<code class="docutils literal notranslate"><span class="pre">access()</span></code> is only checking the permissions for the current user. Furthermore, <code class="docutils literal notranslate"><span class="pre">access()</span></code> can
check more than just the standard read, write, and execute bits, so this mode does not follow the
same octal structure.</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</span> <span class="pre">access(const</span> <span class="pre">char</span> <span class="pre">*path,</span> <span class="pre">int</span> <span class="pre">mode);</span></code></dt>
<dd>Check for permission to access the specified file.</dd>
</dl>
</div>
<p><a class="reference external" href="Files.html#cla-59">Code Listing A.59</a> uses <code class="docutils literal notranslate"><span class="pre">access()</span></code> to determine if a file is readable. Intuitively,
the <code class="docutils literal notranslate"><span class="pre">R_OK</span></code>, <code class="docutils literal notranslate"><span class="pre">W_OK</span></code>, and <code class="docutils literal notranslate"><span class="pre">X_OK</span></code> arguments (which can be successfully combined with bit-wise OR)
check for read, write, and execute permissions. The <code class="docutils literal notranslate"><span class="pre">F_OK</span></code> argument could be used to check just if
the file exists, regardless of the other access permissions. Different systems also support
additional values that could allow the user to check if a file can be deleted, if the user can
change its permissions, and so forth; these options are system-specific, though, and are not widely used.</p>
<blockquote id="cla-59">
<div><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
9
10
11
12
13
14
15
16</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.59:</span>
<span class="cm"> Checking for read permission to access a file</span>
<span class="cm"> */</span>
<span class="cm">/* Check for permission */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">access</span> <span class="p">(</span><span class="s">&quot;data.txt&quot;</span><span class="p">,</span> <span class="n">R_OK</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Access failed, so check global errno to determine why.</span>
<span class="cm"> Requires including &lt;errno.h&gt; */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">errno</span> <span class="o">==</span> <span class="n">EACCES</span><span class="p">)</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Access denied</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span>
<span class="nf">printf</span> <span class="p">(</span><span class="s">&quot;Access failed for other error</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Access granted</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
</div></blockquote>
<p>The <code class="docutils literal notranslate"><span class="pre">unistd.h</span></code> header file provides additional functions that are relevant to the discussion of
access permissions. The <code class="docutils literal notranslate"><span class="pre">chown()</span></code> and <code class="docutils literal notranslate"><span class="pre">fchown()</span></code> functions provide interfaces to change which
user or group is considered the files owner. These functions are generally restricted in certain
ways; clearly, it would not be advisable to allow a random user to take over anothers files by
changing their ownership. Some systems allow users to run these functions only on files that they
own, whereas others restrict access to these functions to system adminstrators.</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</span> <span class="pre">chown(const</span> <span class="pre">char</span> <span class="pre">*path,</span> <span class="pre">uid_t</span> <span class="pre">owner,</span> <span class="pre">gid_t</span> <span class="pre">group);</span></code></dt>
<dd>Change the ownership of a file path.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">fchown(int</span> <span class="pre">fildes,</span> <span class="pre">uid_t</span> <span class="pre">owner,</span> <span class="pre">gid_t</span> <span class="pre">group);</span></code></dt>
<dd>Change the ownership of a file specified by a file descriptor.</dd>
</dl>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">getuid()</span></code>, <code class="docutils literal notranslate"><span class="pre">geteuid()</span></code>, <code class="docutils literal notranslate"><span class="pre">getgid()</span></code>, and <code class="docutils literal notranslate"><span class="pre">getegid()</span></code> functions are not about files, per se, but they are relevant to the current discussion. These functions get information about the current process that is executing. Whenever you run a program, you create a process; the process inherits a specified user ID and group ID that control the processs access. Consequently, when the previous examples referred to checking the “users” access to a file, this check is based on the user ID associated with the process executing this 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 &lt;unistd.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">uid_t</span> <span class="pre">getuid(void);</span></code></dt>
<dd>Gets the real user ID of the calling process.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">uid_t</span> <span class="pre">geteuid(void);</span></code></dt>
<dd>Gets the effective user ID of the calling process.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">gid_t</span> <span class="pre">getgid(void);</span></code></dt>
<dd>Gets the real group ID of the calling process.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">gid_t</span> <span class="pre">getegid(void);</span></code></dt>
<dd>Gets the effective group ID of the calling process.</dd>
</dl>
</div>
<p>The functions below make a distinction between the <em>real user</em> and the <em>effective user</em>.
(All of the points here also apply to the real group and effective group; we only mention the user
for brevity.) The real user is the ID of the account that initiated the creation of the process,
whereas the effective user is the one attached to the process as it runs; these IDs are typically
the same, but they do not have to be. Functions that check permissions, such as <code class="docutils literal notranslate"><span class="pre">access()</span></code>,
generally use the effective user ID, though there are exceptions where the real user ID can also
influence access decisions.</p>
<p>As an example of the distinction between the real and effective user, consider an executable file
with the <code class="docutils literal notranslate"><span class="pre">SETUID</span></code> bit set (see Chapter 2); this bit sets the processs effective user ID to be the
user ID of the executable files owner, rather than the user who ran the command. One common use of
this is to have the <code class="docutils literal notranslate"><span class="pre">SETUID</span></code> bit set on a file owned by the administrative (<code class="docutils literal notranslate"><span class="pre">root</span></code>) account; the
process that runs will then have full access to the system, as it is running as root rather than a
restricted user account. This technique is how a login program can run to check a users password
against the full password list, but the user does not have direct access to the password file.</p>
<p>Another example of the real vs. user distinction can be manually created with the su command.
Contrary to a common belief, <code class="docutils literal notranslate"><span class="pre">su</span></code> does not necessarily mean “super user” (a common term for
<code class="docutils literal notranslate"><span class="pre">root</span></code>); rather, su means <em>substitute user</em>. Running a command with <code class="docutils literal notranslate"><span class="pre">su</span></code> will change the
effective user ID of the process, even if the <code class="docutils literal notranslate"><span class="pre">SETUID</span></code> bit is not set. For example, the following
command line would run the <code class="docutils literal notranslate"><span class="pre">ls</span></code> command based on the <code class="docutils literal notranslate"><span class="pre">csf</span></code> username <a class="footnote-reference" href="Files.html#f61" id="id3">[1]</a>, rather than the
default user typing the command. Consequently, the permission checks (to determine if the process is
allowed to list the current directorys file contents) are based on the <code class="docutils literal notranslate"><span class="pre">csf</span></code> username, not the
actual user.</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>$ su csf ls -ltr
</pre></div>
</div>
</div>
<div class="section" id="persistent-storage">
<h2>10.9.2. Persistent Storage<a class="headerlink" href="Files.html#persistent-storage" title="Permalink to this headline"></a></h2>
<p>Chapter 2 covers most of the details about working with files, such as reading from and writing to
them. That section, however, uses a broader definition of files than this part of the Appendix.
Here, we are focusing just on files in the traditional, common sense; i.e., those that are
persistently stored on a device such as a hard drive. The storage techniques used for these files
raise particular issues that are beneficial to understand for systems programming.</p>
<p>The first issue, which we have already discussed, is that of metadata. When a file is stored, the
metadata is stored in an inode structure. It is important to realize two facts: 1) the inode—not the
contents—actually defines the file, and 2) the inode is stored separately from the contents. In
other words, the inode—which is stored on the device—contains information to identify other blocks
of data on the device that store the files contents. When a file is modified, the new contents may
be written to the existing blocks, but maybe not. The new contents may be written to different
blocks, and the inode is simply changed to point to these new blocks; the old content blocks are
still present on the device, the inode just doesnt point to them anymore. Similarly, when a file is
deleted, the content blocks are not necessarily destroyed; just the inode is deleted (in fact,
thats not even entirely true, as we will describe in relation to directories).</p>
<p>When a file is in use (such as when you are editing a source code file in a text editor), all of the
file contents exist in memory. Generally speaking, you are not directly interfacing with the file
stored on disk; compared to accessing a copy in memory, accessing the stored copy would be
horrendously slow. As you modify the file, the version in memory and the original stored copy become
different. The unistd.h header file defines three key functions for fixing this. The <code class="docutils literal notranslate"><span class="pre">ftruncate()</span></code>
and <code class="docutils literal notranslate"><span class="pre">trunctate()</span></code> functions are used to resize <a class="footnote-reference" href="Files.html#f62" id="id4">[2]</a> the files in-memory representation; for
instance, if you delete a large chunk of your programs code, the text editor may run <code class="docutils literal notranslate"><span class="pre">truncate()</span></code>
to reduce the memory allocated for it.</p>
<p>These changes are not automatically propagated to the inode stored on the device. This update
typically (the details depend on the OS and the file system in use) only occurs when the file is
closed or when the process calls <code class="docutils literal notranslate"><span class="pre">fsync()</span></code>. The <code class="docutils literal notranslate"><span class="pre">fsync()</span></code> function—which is run when you save a
file—writes the contents to the storage device and updates the stored inode accordingly.</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</span> <span class="pre">fsync(int</span> <span class="pre">fildes);</span></code></dt>
<dd>Synchronize the in-memory file contents with persistent storage.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">ftruncate(int</span> <span class="pre">fildes,</span> <span class="pre">off_t</span> <span class="pre">length);</span></code></dt>
<dd>Truncate or extend a file size to the specified length.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">truncate(const</span> <span class="pre">char</span> <span class="pre">*path,</span> <span class="pre">off_t</span> <span class="pre">length);</span></code></dt>
<dd>Truncate or extend a file size to the specified length.</dd>
</dl>
</div>
</div>
<div class="section" id="directories-and-links">
<h2>10.9.3. Directories and Links<a class="headerlink" href="Files.html#directories-and-links" title="Permalink to this headline"></a></h2>
<p>It is likely that the reader is familiar with the term <em>directory</em> as it is used in relation to
files. When working at the systems level, it helps to have a more in-depth understanding than the
basic idea of directories (or folders) as places where files are stored. Specifically, it is
important to note that <strong>files are not actually stored in directories</strong>. As noted above, a file is
defined by an inode, as persistent data structure that contains the files metadata and pointers to
the files contents. The location of the inode on the device is determined by the OS and the file
system. The <em>inode number</em> is a persistent location identifier that tells the OS where to find
the inode on the device.</p>
<p>From this perspective of inodes, one may observe that we have not mentioned the concept of file
names. The reason for this is that <strong>file names do not, in fact, identify files</strong>. When we are
working at the level of inodes, files do not have names. Names are introduced by the concept of
directories. A directory is simply a special type of file that contains a mapping between a string
(name) and the corresponding inode. <a href="Files.html#filesysblocks">Figure 10.9.7</a> illustrates this concept
for two directories and two regular files.</p>
<div class="figure mb-2 align-center" id="id6">
<span id="filesysblocks"></span><a class="reference internal image-reference" href="_images/CSF-Images.A.8.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Sample blocks containing inodes and a directory's contents" src="_images/CSF-Images.A.8.png" style="width: 90%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 10.9.7: Sample blocks containing inodes and a directorys contents</span></p>
</div>
<p>To start, assume that we are examining the directory <code class="docutils literal notranslate"><span class="pre">/home/csf</span></code>. Since directories are files
(just a special type of file), this directory has an inode and an inode number. In <a href="Files.html#filesysblocks">Figure 10.9.7</a>, the inode number for <code class="docutils literal notranslate"><span class="pre">/home/csf</span></code> is 4526, which identifies the block <a class="footnote-reference" href="Files.html#f63" id="id5">[3]</a>
of that number. That inode indicates that the file is a directory with permissions set to
<code class="docutils literal notranslate"><span class="pre">0755</span></code>, etc. The <code class="docutils literal notranslate"><span class="pre">Content</span></code> field indicates the block number containing the directorys contents.
By examining the contents in block 51003 (the block number and the inode number are the same), we
can see that this directory contains three files: <code class="docutils literal notranslate"><span class="pre">data.txt</span></code>, <code class="docutils literal notranslate"><span class="pre">script.py</span></code>, and <code class="docutils literal notranslate"><span class="pre">private.</span></code> The
directory indicates that the string <code class="docutils literal notranslate"><span class="pre">&quot;data.txt&quot;</span></code> (or the full path <code class="docutils literal notranslate"><span class="pre">/home/csf/data.txt</span></code>) refers
to inode 4873. This inode indicates that the file is a regular file and its contents begin at block
52002. (For historical reasons, blocks are 512 bytes in size; if the file exceeds 512 bytes, it will
require multiple content blocks.) Similarly, blocks 5922 and 202 contain the inodes for <code class="docutils literal notranslate"><span class="pre">script.py</span></code>
and <code class="docutils literal notranslate"><span class="pre">private</span></code>, respectively; the inode for the latter indicates that <code class="docutils literal notranslate"><span class="pre">private</span></code> is a directory.</p>
<p>Readers who have become comfortable with working on the command line are likely to have heard
references to “being in” or “changing to” a directory. These phrases refer to examining or changing
the current processs <em>current working directory</em>, the default location that the process will
look for files. Note that, when you are working on the command line, you are always running a
process: the shell (typically <code class="docutils literal notranslate"><span class="pre">bash</span></code>). The <code class="docutils literal notranslate"><span class="pre">cd</span></code> command tells the <code class="docutils literal notranslate"><span class="pre">bash</span></code> process to change its
current working directory. When you run a separate program by typing a command, bash creates a new
process, and that new process inherits bashs current working directory; this new process could
change its current working directory with the <code class="docutils literal notranslate"><span class="pre">chdir()</span></code> and <code class="docutils literal notranslate"><span class="pre">fchdir()</span></code> functions.</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</span> <span class="pre">chdir(const</span> <span class="pre">char</span> <span class="pre">*path);</span></code></dt>
<dd>Change the current working directory based on the provided <code class="docutils literal notranslate"><span class="pre">path</span></code>.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">fchdir(int</span> <span class="pre">fd);</span></code></dt>
<dd>Change to the directory given as the open file descriptor <code class="docutils literal notranslate"><span class="pre">fd</span></code>.</dd>
</dl>
</div>
<p>At this point, we have established that directories do not contain files or inodes; they just map a
string to an inode number. Similarly, the <code class="docutils literal notranslate"><span class="pre">chdir()</span></code> function can change which directory the
process will look in by default. Based on this understanding, we can now distinguish between
<em>hard links</em> and <em>symbolic links</em>. A hard link is a
directory reference to an inode. In <a href="Files.html#filesysblocks">Figure 10.9.7</a>, block 51003 contains an
entry for <code class="docutils literal notranslate"><span class="pre">data.txt</span></code> that links to inode 4873. Within inode 4873, there is a field that counts the
number of such links; so 4873s link count would be at least one. This figure did not show the
contents of the <code class="docutils literal notranslate"><span class="pre">/home/csf/private</span></code> directory, but assume that it contains an entry for a file
named copy.txt that also maps to inode 4873; i.e., there is a <code class="docutils literal notranslate"><span class="pre">/home/csf/private/copy.txt</span></code> file,
and it points to the same inode as <code class="docutils literal notranslate"><span class="pre">/home/csf/data.txt</span></code>. In other words, the full path names
<code class="docutils literal notranslate"><span class="pre">/home/csf/data.txt</span></code> and <code class="docutils literal notranslate"><span class="pre">/home/csf/private/copy.txt</span></code> are both hard links to the same inode and
the inodes reference count must be at least two. The effect of this hard link is that these two
files are the same; changing the contents of one will change the other. Such hard links are created
with the <code class="docutils literal notranslate"><span class="pre">link()</span></code> function.</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</span> <span class="pre">link(const</span> <span class="pre">char</span> <span class="pre">*path1,</span> <span class="pre">const</span> <span class="pre">char</span> <span class="pre">*path2);</span></code></dt>
<dd>Make <code class="docutils literal notranslate"><span class="pre">path2</span></code> a hard link with the same attributes as <code class="docutils literal notranslate"><span class="pre">path1</span></code>.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">symlink(const</span> <span class="pre">char</span> <span class="pre">*path1,</span> <span class="pre">const</span> <span class="pre">char</span> <span class="pre">*path2);</span></code></dt>
<dd>Make <code class="docutils literal notranslate"><span class="pre">path2</span></code> a symbolic link to the file identified by <code class="docutils literal notranslate"><span class="pre">path1</span></code>.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">unlink(const</span> <span class="pre">char</span> <span class="pre">*path);</span></code></dt>
<dd>Remove a link to a file specified by the given <code class="docutils literal notranslate"><span class="pre">path</span></code>.</dd>
</dl>
</div>
<p>Unlike changes to a file, the <code class="docutils literal notranslate"><span class="pre">unlink()</span></code> function only removes a single such link by deleting the
entry from the relevant directory. That is, calling <code class="docutils literal notranslate"><span class="pre">unlink()</span></code> on <code class="docutils literal notranslate"><span class="pre">/home/csf/private/copy.txt</span></code>
would remove the entry for <code class="docutils literal notranslate"><span class="pre">copy.txt</span></code> from the <code class="docutils literal notranslate"><span class="pre">/home/csf/private</span></code> directory. The file contents
could still be accessed using the <code class="docutils literal notranslate"><span class="pre">/home/csf/data.txt</span></code> path name. As long as there is at least one
reference to the file contents, the file cannot actually be “deleted” in the casual sense. In fact,
even when the reference count for an inode drops to 0, the contents are not necessarily destroyed.
Instead, the blocks containing the inode and the file contents are marked as available for future
use. Neither is truly destroyed until they are overwritten when they are assigned to a different
file in the future.</p>
<p>In contrast to hard links, a symbolic link (also known as a <em>shortcut</em> in the Windows family of OS)
is a distinct file with its own inode. The inodes type field would indicate that it is a symbolic
link (or symlink for short) rather than a regular file. The inodes Content would point to a content
block just like a regular file; however, the contents would be the path name that the symbolic link
points to. To illustrate the difference, consider the following command lines, which start with an
original C source file called <code class="docutils literal notranslate"><span class="pre">hello.c</span></code>:</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>$ ln hello.c link.c
$ ln -s hello.c symlink.c
$ ls -li hello.c link.c symlink.c
12909398185 -rw-r--r-- 2 csf staff 74 Feb 23 17:09 hello.c
12909398185 -rw-r--r-- 2 csf staff 74 Feb 23 17:09 link.c
12909398210 lrwxr-xr-x 1 csf staff 7 Feb 23 17:10 symlink.c -&gt; hello.c
</pre></div>
</div>
<p>The first <code class="docutils literal notranslate"><span class="pre">ln</span></code> command uses link() to make <code class="docutils literal notranslate"><span class="pre">link.c</span></code> a hard link to the contents of <code class="docutils literal notranslate"><span class="pre">hello.c</span></code>.
The <code class="docutils literal notranslate"><span class="pre">-s</span></code> flag on the second <code class="docutils literal notranslate"><span class="pre">ln</span></code> command calls <code class="docutils literal notranslate"><span class="pre">symlink()</span></code> instead, making <code class="docutils literal notranslate"><span class="pre">symlink.c</span></code> a
symbolic link to <code class="docutils literal notranslate"><span class="pre">hello.c</span></code>; that is, <code class="docutils literal notranslate"><span class="pre">symlink.c</span></code> is a distinct special file whose contents are
the literal string <code class="docutils literal notranslate"><span class="pre">&quot;hello.c&quot;</span></code> to indicate the target of the link. (Note that the symbolic link
does not actually check for—or have any knowledge of—the existence of <code class="docutils literal notranslate"><span class="pre">hello.c</span></code> itself.) The <code class="docutils literal notranslate"><span class="pre">ls</span>
<span class="pre">-li</span></code> command shows metadata about the three files. The first field on each line is the respective
inode number (produced by the <code class="docutils literal notranslate"><span class="pre">-i</span></code> flag). Since <code class="docutils literal notranslate"><span class="pre">hello.c</span></code> and <code class="docutils literal notranslate"><span class="pre">link.c</span></code> are hard links to the
same contents, their inode is the same. On the other hand, <code class="docutils literal notranslate"><span class="pre">symlink.c</span></code> is a separate file with a
distinct inode number.</p>
<p>One of the key differences between hard links and symbolic links can be observed through deletion.
Hard links are bound to the actual file contents, whereas symbolic links are bound to the name. If
the target of a symbolic link (<code class="docutils literal notranslate"><span class="pre">hello.c</span></code> in this case) is deleted (the <code class="docutils literal notranslate"><span class="pre">rm</span></code> command calls
<code class="docutils literal notranslate"><span class="pre">unlink()</span></code> on the <code class="docutils literal notranslate"><span class="pre">hello.c</span></code> file name) and recreated with the same name, accessing the symbolic
link will reflect the new contents; accessing the other hard link will get the old contents. The
original contents will only be deleted when all hard links are removed.</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>$ rm hello.c
$ cat link.c
[original contents here...omitted for brevity]
$ cat symlink.c
cat: symlink.c: No such file or directory
$ echo &quot;goodbye&quot; &gt; hello.c
$ cat link.c
[original contents here...omitted for brevity]
$ cat symlink.c
goodbye
</pre></div>
</div>
</div>
<div class="section" id="advisory-locks">
<h2>10.9.4. Advisory Locks<a class="headerlink" href="Files.html#advisory-locks" title="Permalink to this headline"></a></h2>
<p>When concurrent software is working with files, there is the danger that multiple processes or
threads might try to access or modify an existing file at the same time. This situation would allow
one process or thread to change the files contents in ways that can cause errors in the other
process or thread. Different OS and file systems provide a variety of mechanisms to prevent this
from happening; as these approaches can vary between systems, it can be difficult to rely on them
for cross-platform software. One mechanism that generally has cross-platform support is the use of
<em>advisory locks</em>, which provide a mechanism for cooperating processes to try
to avoid this situation. In essence, an advisory lock allows a process to check if another process
has already locked the file; if so, the new process can wait until the first process is finished. As
the name implies, though, these are advisory in nature; the new process can still proceed regardless
of the first processs claim.</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/file.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">flock(int</span> <span class="pre">fd,</span> <span class="pre">int</span> <span class="pre">operation);</span></code></dt>
<dd>Apply or remove an advisory lock on an open file.</dd>
</dl>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">flock()</span></code> function provides one mechanism to create an advisory lock on a file. Unlike some of
the previous functions we have described, <code class="docutils literal notranslate"><span class="pre">flock()</span></code> only works with file descriptors (see Chapter
2), not path names. That is, the process must have access to the file and must have already
successfully opened it. <a class="reference external" href="Files.html#cla-60">Code Listing A.60</a> demonstrates the use of flock(). (Note that
this code relies on <code class="docutils literal notranslate"><span class="pre">fork()</span></code> and <code class="docutils literal notranslate"><span class="pre">open()</span></code>, which are explained in Chapter 2. Advisory locks are
not a critical topic for the main chapter and are provided here for reference after that chapter has
been completed.)</p>
<blockquote id="cla-60">
<div><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
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 A.60:</span>
<span class="cm"> Setting an advisory lock on a file using the flock() interface</span>
<span class="cm"> */</span>
<span class="cm">/* Create a child process and race to get the file */</span>
<span class="kt">pid_t</span> <span class="n">child</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</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Both parent and child will open the file */</span>
<span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">open</span> <span class="p">(</span><span class="s">&quot;movies.csv&quot;</span><span class="p">,</span> <span class="n">O_RDWR</span><span class="p">);</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">fd</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Only one will succeed in locking it */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">flock</span> <span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">LOCK_EX</span> <span class="o">|</span> <span class="n">LOCK_NB</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Successfully locked file</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="k">else</span>
<span class="nf">printf</span> <span class="p">(</span><span class="s">&quot;Failed to lock</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">close</span> <span class="p">(</span><span class="n">fd</span><span class="p">);</span>
<span class="cm">/* Add a slight pause to observe the locking */</span>
<span class="n">sleep</span> <span class="p">(</span><span class="mi">2</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
</div></blockquote>
<p>The <code class="docutils literal notranslate"><span class="pre">LOCK_EX</span> <span class="pre">|</span> <span class="pre">LOCK_NB</span></code> argument specifies that this process is requesting exclusive (<code class="docutils literal notranslate"><span class="pre">LOCK_EX</span></code>)
access to the file (only one access at a time) and <code class="docutils literal notranslate"><span class="pre">flock()</span></code> should run in non-blocking mode
(<code class="docutils literal notranslate"><span class="pre">LOCK_NB</span></code>). The default behavior of <code class="docutils literal notranslate"><span class="pre">flock()</span></code> is to cause current process to wait (block) if
another process already has exclusive access. In non-blocking mode, <code class="docutils literal notranslate"><span class="pre">flock()</span></code> returns a non-zero
value to indicate that the current process failed to acquire the lock. The process can then proceed
to other work that may be necessary and try to acquire the lock at a later time. The call to
<code class="docutils literal notranslate"><span class="pre">sleep()</span></code> on line 21 is included in this example to create a slight pause in both processes. That
is, without this <code class="docutils literal notranslate"><span class="pre">sleep()</span></code>, it is possible that one process would run, acquire the lock, and exit
(releasing the lock) before the other process had a chance to try for access. Including line 21
makes such timing unlikely, increasing the likelihood that the reader can observe the effects of the
failed lock when running this code.</p>
<p>In the preceding discussion, we mentioned that advisory locks allow <em>cooperating</em> processes to
coordinate their work. To be precise, two processes are cooperating in this sense only if they
originate from the same original process. That is, the process specifically uses <code class="docutils literal notranslate"><span class="pre">fork()</span></code> to
create at least one child process. Running the same program multiple times does not create
cooperating processes; these processes would not recognize each others claims to locking the file.</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>Although it is generally cross-platform, <code class="docutils literal notranslate"><span class="pre">flock()</span></code> does not successfully create advisory locks on
macOS. For code that truly needs to be cross-platform, <code class="docutils literal notranslate"><span class="pre">fcntl()</span></code> is the required interface for
advisory locks. The primary disadvantage of <code class="docutils literal notranslate"><span class="pre">fcntl()</span></code> is that it is an older, generic interface
for many different operations on files. Advisory locks are just one of the possible operations.</p>
</div>
<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;fcntl.h&gt;</p><hr class="mt-1" />
<dl class="docutils">
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">fcntl(int</span> <span class="pre">fildes,</span> <span class="pre">int</span> <span class="pre">cmd,</span> <span class="pre">...);</span></code></dt>
<dd>Perform an operation on a file descriptor.</dd>
</dl>
</div>
<p><a class="reference external" href="Files.html#cla-61">Code Listing A.61</a> demonstrates the <code class="docutils literal notranslate"><span class="pre">fcntl()</span></code> interface for creating an advisory lock.
On lines 19 and 26, the <code class="docutils literal notranslate"><span class="pre">F_SETLK</span></code> argument tells <code class="docutils literal notranslate"><span class="pre">fcntl()</span></code> that the process is trying to set or
release a lock; the <code class="docutils literal notranslate"><span class="pre">struct</span></code> reference passed as the third argument distinguishes between these
two actions. Specifically, setting the <code class="docutils literal notranslate"><span class="pre">struct</span></code>s <code class="docutils literal notranslate"><span class="pre">l_type</span></code> field to <code class="docutils literal notranslate"><span class="pre">F_WRLCK</span></code> indicates the
process is requesting a lock for writing to the file; locking the file for reading would require
also setting the <code class="docutils literal notranslate"><span class="pre">F_RDLCK</span></code> bit in this field. Setting the <code class="docutils literal notranslate"><span class="pre">l_type</span></code> field to <code class="docutils literal notranslate"><span class="pre">F_UNLCK</span></code> and
calling <code class="docutils literal notranslate"><span class="pre">fcntl()</span></code> again releases the lock on the file.</p>
<blockquote id="cla-61">
<div><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
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.61:</span>
<span class="cm"> Setting an advisory lock on a file using the fcntl() interface</span>
<span class="cm"> */</span>
<span class="cm">/* Create a child process then race to get the file */</span>
<span class="kt">pid_t</span> <span class="n">child</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</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Both parent and child will open the file */</span>
<span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">open</span> <span class="p">(</span><span class="s">&quot;movies.csv&quot;</span><span class="p">,</span> <span class="n">O_RDWR</span><span class="p">);</span>
<span class="n">assert</span> <span class="p">(</span><span class="n">fd</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">);</span>
<span class="cm">/* Initialize the lock for writing */</span>
<span class="k">struct</span> <span class="n">flock</span> <span class="n">lock</span><span class="p">;</span>
<span class="n">memset</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">lock</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">lock</span><span class="p">));</span>
<span class="n">lock</span><span class="p">.</span><span class="n">l_type</span> <span class="o">=</span> <span class="n">F_WRLCK</span><span class="p">;</span>
<span class="cm">/* Only one will succeed in locking it */</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fcntl</span> <span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">F_SETLK</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">lock</span><span class="p">)</span> <span class="o">==</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;Successfully locked file</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="cm">/* Add a slight pause to observe the locking */</span>
<span class="n">sleep</span> <span class="p">(</span><span class="mi">2</span><span class="p">);</span>
<span class="cm">/* Now release the lock */</span>
<span class="n">lock</span><span class="p">.</span><span class="n">l_type</span> <span class="o">=</span> <span class="n">F_UNLCK</span><span class="p">;</span>
<span class="n">fcntl</span> <span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">F_SETLK</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">lock</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Failed to lock</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">close</span> <span class="p">(</span><span class="n">fd</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
</div></blockquote>
<table class="docutils footnote" frame="void" id="f61" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="Files.html#id3">[1]</a></td><td>In the UNIX tradition, <em>username</em> refers to the human-readable identifier that user can
remember and use easily. Internally, all usernames are mapped to a user ID, which is just an integer value.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="f62" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="Files.html#id4">[2]</a></td><td>These functions are poorly named. The standard definition of the word “truncate” means to
reduce the size of something. However, the C <code class="docutils literal notranslate"><span class="pre">truncate()</span></code> function can also be used to increase the files size.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="f63" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="Files.html#id5">[3]</a></td><td>Typical storage devices organize the device into what is essentially a gigantic array of
fixed-size blocks. While the details are more complicated than this, it is sufficient for our
purposes to think of accessing a block just as we would index an array.</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="FunctionPointers.html">10.8. Function Pointers</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="Glossary.html">11.1. Glossary</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>