CHAPTER 1 Unix Systems Programming: The Big Picture
1.1 Introduction
1.2 What Is Systems Programming?

1.2.1 The Simple Program Model
1.2.2 Face Reality
1.2.3 The Role of the Operating System
1.2.4 Providing Services to Programs
1.3 Understanding Systems Programming
1.3.1 System Resources
1.3.2 Our Goal: Understanding Systems Programming
1.3.3 Our Method:Three Simple Steps
1.4 Unix from the User Perspective
1.4.1 What Does Unix Do?
1.4.2 Log In-Run Programs-Log Out
1.4.3 Working with Directories
1.4.4 Working with Files
1.5 Unix from the Larger Perspective
1.5.1 Connections between Users and Programs
1.5.2 Internet Bridge Tournaments
1.5.3 be: The Secret Life of a Unix Desk Calculator
1.5.4 From bc/dc to the Web

1.6 Can I Try to Do One?
1.7 A Lot of Questions and a Map

1.7.1 What Now?
1.7.2 And Now for the Map
1.7.3 What Is Unix? History and Dialects
Summary
CHAPTER 2 Users, Files, and the Manual: who Is First?
2.1 Introduction
2.2 Asking about who
2.2.1 Commands Are Programs
2.3 Question 1: What Does who Do?
2.3.1 Reading the Manual
f
viii Table of Contents
2.4 Question 2: How Does who Do It?
2.4.1 We Now Know How who Works
2.5 Question 3: Can I Write who?

2.5.1 Question: How Do I Read structs from a File?
2.5.2 Answer: Use open, read, and close
2.5.3 Writing whol. с
2.5.4 Displaying Log-In Records
2.5.5 Writing who2. с
2.5.6 A Look Back and a Look Forward
2.6 Project Two: Writing cp (read and write)
2.6.1 Question 1: What does cp do?
2.6.2 Question 2: How Does cp Create and Write?
2.6.3 Question 3: Can I Write cp?
2.6.4 Unix Programming Seems Pretty Easy
2.7 More Efficient File I/O: Buffering
2.7.1 Does the Size of the Buffer Matter?
2.7.2 Why System Calls Are Time Consuming
2.7.3 Does This Mean That who2. с Is Inefficient?
2.7.4 Adding Buffering to who2. с
2.8 Buffering and the Kernel
2.8.1 If Buffering Is So Smart, Why Doesn\'t the Kernel Do It?
2.9 Reading and Writing a File
2.9.1 Logging Out: What It Does
2.9.2 Logging Out: How It Works
2.9.3 Moving the Current Position: Iseek
2.9.4 Code to Log Out from a Terminal
2.10 What to Do with System-Call Errors
Summary
Explorations Programming Exercises Projects A Final Puzzler: The tail Command
CHAPTER 3 Directories and File Properties: Looking through Is
3.1 Introduction
3.2 Question 1: What Does Is Do?

3.2.1 is Lists Names of Files and Reports File Attributes
3.2.2 Listing Other Directories, Reporting on Other Files
3.2.3 Popular Command-Line Options
3.2.4 Answer One: A Summary

3.3 Brief Review of the File System Tree
3.4 Question 2: How Does Is Work?

3.4.1 What Is a Directory, Anyway?
3.4.2 Do open, read, and close Work for Directories?
3.4.3 OK, OK, How Do I Read a Directory?
Question 3: Can I Write is? 3.5.1 How Did We Do? Project Two: Writing is -l
3.6.1 Question 1: What Does Is -1 Do?
3.6.2 Question 2: How Does Is -iWork?
3.6.3 Answer:The stat Call Gets File Information
3.6.4 What Other Information Does stat Provide?
3.6.5 How\'dWeDo?
3.6.6 Converting File Mode to a String
3.6.7 Converting User/Group ID to Strings
3.6.8 Putting It All Together: Is2. с
The Three Special Bits

3.7.1 The Set-User-ID Bit
3.7.2 The Set-Group-ID Bit
3.7.3 The Sticky Bit
3.7.4 The Special Bits and Is -l
Summary of Is
Setting and Modifying the Properties of a File
3.9.1 Type of a File
3.9.2 Permission Bits and Special Bits
3.9.3 Number of Links to a File
3.9.4 Owner and Group of a File
3.9.5 Size of a File
3.9.6 Modification and Access Time
3.9.7 Name of a File
nary
Explorations Programming Exercises Projects
on File Systems: Writing pwd
Introduction
A User\'s View of the File System
4.2.1 Directories and Files
4.2.2 Directory Commands
4.2.3 File Commands
4.2.4 Tree Commands
4.2.5 Almost No Limits to Tree Structure
4.2.6 Summary of the Unix File System
Internal Structure of the Unix File System

4.3.1 Abstraction Zero: From Platters to Partitions
4.3.2 Abstraction One: From Platters to an Array of Blocks
4.3.3 Abstraction Two: From an Array of Blocks to
Three Regions
4.3.4 The File System in Practice: Creating a File
4.3.5 The File System in Practice: How Directories Work
4.3.6 The File System in Practice: How cat Works
4.3.7 Inodes and Big Files
4.3.8 Variations on the Unix File System
4.4 Understanding Directories
4.4.1 Understanding Directory Structure
4.4.2 Commands and System Calls for Directory Trees
4.5 Writing pwd
4.5.1 How pwd Works
4.5.2 A Version of pwd
4.6 Multiple File Systems: A Tree of Trees
4.6.1 Mount Points
4.6.2 Duplicate Inode Numbers and Cross-Device Links
4.6.3 Symbolic Links: Panacea or Pasta City?
Summary
Explorations Programming Exercises Projects
CHAPTER 5 Connection Control: Studying stty
5.1 Programming for Devices
5.2 Devices Are Just Like Files

5.2.1 Devices Have Filenames
5.2.2 Devices and System Calls
5.2.3 Example: Terminals Are Just Like Files
5.2.4 Properties of Device Files
5.2.5 Writing write
5.2.6 Device Files and Inodes
5.3 Devices Are Not Like Files
5.3.1 Connection Attributes and Control
5.4 Attributes of Disk Connections
5.4.1 Attribute 1: Buffering
5.4.2 Attribute 2: Auto-Append Mode
5.4.3 Controlling File Descriptors with open
5.4.4 Summary of Disk Connections
5.5 Attributes of Terminal Connections
5.5.1 Terminal I/O Is Not as Simple as It Appears
5.5.2 The Terminal Driver
5.5.3 The stty Command
5.5.4 Programming the Terminal Driver:The Settings
5.5.5 Programming the Terminal Driver: The Functions
5.5.6 Programming the Terminal Driver: The Bits
5.5.7 Programming the Terminal Driver: Sample Programs
5.5.8 Summary of Terminal Connections

5.6 Programming Other Devices: ioctl
5.7 Up in the Sky! It\'s a File, It\'s a Device, It\'s a STREAM!
Summary
Explorations Programming Exercises Projects
Programming for Humans: Terminal Control and Signals
6.1 Software Tools vs. Device-Specific Programs
6.2 Modes of the Terminal Driver

6.2.1 Canonical Mode: Buffering and Editing
6.2.2 Noncanonical Processing
6.2.3 Summary of Terminal Modes

6.3 Writing a User Program: play_again. с
6.3.1 Nonblocking Input: play_again3. с
6.4 Signals

6.4.1 What Does Ctrl-C Do?
6.4.2 What Is a Signal?
6.4.3 What Can a Process Do about a Signal?
6.4.4 Examples of Signal Handling

6.5 Prepared for Signals: play_again4. с
6.6 Processes are Mortal
6.7 Programming for Devices
Summary
Explorations Programming Exercises
Event-Driven Programming: Writing a Video Game
7.1 Video Games and Operating Systems
7.2 The Project: Write Single-Player pong
7.3 Space Programming: The curses Library

7.3.1 Introduction to curses
7.3.2 Curses Internals: Virtual and Real Screens

7.4 Time Programming: sleep
7.5 Programming with Time I: Alarms

7.5.1 Adding a Delay: sleep
7.5.2 How sleep () Works: Using Alarms in Unix
7.5.3 Scheduling a Future Action
7.6 Programming with Time II: Interval Timers
7.6.1 Adding a Finer Delay: usleep
7.6.2 Three Kinds of Timers: Real, Process, Profile
7.6.3 Two Kinds of Intervals: Initial and Repeating
7.6.4 Programming with the Interval Timers
7.6.5 How Many Clocks Does the Computer Have?
7.6.6 Summary of Timers
7.7 Signal Handling I: Using signal
7.7.1 Old-Style Signal Handling
7.7.2 Handling Multiple Signals
xii Table of Contents
7.7.3 Testing Multiple Signals
7.7.4 More signal Weaknesses
7.8 Signal Handling II: sigaction
7.8.1 Handling Signals: sigaction
7.8.2 Summary of Signals
7.9 Protecting Data from Corruption
7.9.1 Examples of Data Corruption
7.9.2 Critical Sections
7.9.3 Blocking Signals: sigprocmask and sigsetops
7.9.4 Reentrant Code: Dangers of Recursion
7.9.5 Critical Sections in Video Games

7.10 kill: Sending Signals from a Process
7.11 Using Timers and Signals: Video Games

7.11.1 bounceld. с: Controlled Animation on a Line
7.11.2 bounce2d. c: Animation in Two Dimensions
7.11.3 Now for the Complete Game
7.12 Signals on Input: Asynchronous I/O
7.12.1 Bouncing with Asynchronous I/O
7.12.2 Method 1: Using O_ASYNC
7.12.3 Method 2: Using aio_read
7.12.4 Do We Need Asynchronous Reads for bounce?
7.12.5 Asynchronous Input, Video Games,
and Operating Systems
Summary
Explorations Programming Exercises Projects
CHAPTER 8 Processes and Programs: Studying sh
8.1 Processes = Programs in Action
8.2 Learning about Processes with ps

8.2.1 System Processes
8.2.2 Process Management and File Management
8.2.3 Computer Memory and Computer Programs

8.3 The Shell: A Tool for Process and Program Control
8.4 How the Shell Runs Programs

8.4.1 The Main Loop of a Shell
8.4.2 Question 1: How Does a Program Run a Program?
8.4.3 Question 2: How Do We Get a New Process?
8.4.4 Question 3: How Does the Parent Wait for the
Child to exit?
8.4.5 Summary: How the Shell Runs Programs

8.5 Writing a Shell: psh2. с
8.5.1 Signals and psh2. с
8.6 Reflection: Programming with Processes
8.7 Extra about exit and exec
exit
Death of a Process: exit and The exec Family
8.7.1 8.7.2 Summary
Explorations Programming Exercises
CHAPTER 9 A Programmable Shell: Shell Variables and the Environment
9.1 Shell Programming
9.2 Shell Scripts: What and Why?
9.2.1 A Shell Scripts: What and Why?
9.3 smshl - Command-Line Parsing
9.3.1 Notes on smshl
9.4 Control Flow in the Shell: Why and How

9.4.1 What if Does
9.4.2 How if Works
9.4.3 Adding if to smsh
9.4.4 smsh2 . c: The Revised Code
9.5 Shell Variables: Local and Global
9.5.1 Using Shell Variables
9.5.2 A Storage System for Variables
9.5.3 Adding Variable Commands: Built-ins
9.5.4 How\'dWeDo?
9.6 The Environment: Personalized Settings
9.6.1 Using the Environment
9.6.2 What is the Environment? How it Works
9.6.3 Adding Environment Handling to smsh
9.6.4 Code for varlib . с
9.7 State-of-the-Shell Report
Summary
Explorations Programming Exercises
CHAPTER 10 I/O Redirection and Pipes
10.1 Shell Programming
10.2 A Shell Application: Watch for Users
10.3 Facts about Standard I/O and Redirection

10.3.1 Fact One: Three Standard File Descriptors
10.3.2 Default Connections: The tty
10.3.3 Output Goes Only to stdout
10.3.4 The Shell, Not the Program, Redirects I/O
10.3.5 Understanding I/O Redirection
10.3.6 Fact Two: The "Lowest- Available-fd" Principle
10.3.7 The Synthesis
10.4 How to Attach stdin to a File
10.4.1 Method 1: close then open
10.4.2 Method 2: open . . close . . dup . . close
xiv Table of Contents
10.4.3 System Call Summary: dup
10.4.4 Method 3: open. .dup2. .close
10.4.5 But the Shell Redirects stdin for Other Programs

10.5 Redirecting I/O for Another Program: who > userlist
10.5.1 Summary of Redirection to Files
10.6 Programming Pipes

10.6.1 Creating a Pipe
10.6.2 Using fork to Share a Pipe
10.6.3 The Finale: Using pipe, fork, and exec
10.6.4 Technical Details: Pipes Are Not Files
Summary
Explorations Programming Exercises
CHAPTER 11 Connecting to Processes Near and Far: Servers and Sockets
11.1 Products and Services
11.2 Introductory Metaphor: A Beverage Interface
11.3 be: A Unix Calculator

11.3.1 Coding be: pipe, fork, dup, exec
11.3.2 Remarks on Coroutines
11.3.3 fdopen: Making File Descriptors Look like Files
11.4 popen: Making Processes Look like Files
11.4.1 What popen Does
11.4.2 Writing popen: Using fdopen
11.4.3 Access to Data: Files, APIs, and Servers
11.5 Sockets: Connecting to Remote Processes
11.5.1 An Analogy: "At the Tone, the Time Will Be ..."
11.5.2 Internet Time, DAP, and Weather Servers
11.5.3 Lists of Services: Weil-Known Ports
11.5.4 Writing timeserv. c: A Time Server
11.5.5 Testing timeserv.c
11.5.6 Writing timeclnt. c: A Time Client
11.5.7 Testing timeclnt. c
11.5.8 Another Server: remote Is
11.6 Software Daemons
Summary
Explorations Programming Exercises
CHAPTER 12 Connections and Protocols: Writing a Web Server
12.1 Spotlight on Servers
12.2 Three Main Operations
12.3 Operations 1 and 2: Making a Connection

12.3.1 Operation 1: Setting Up a Server Socket
12.3.2 Operation 2: Connecting to a Server
12.3.3 socklib.c
12.4 Operation 3: Client/Server Conversation
12.4.1 timeserv/timeclnt Using socklib.c
12.4.2 A Second Version of the Server: Using fork
12.4.3 Server Design Question: DIY or Delegate?
12.5 Writing a Web Server
12.5.1 What a Web Server Does
12.5.2 Planning Our Web Server
12.5.3 The Protocol of a Web Server
12.5.4 Writing a Web Server

12.5.5 Running the Web Server
12.5.6 Webserv Source Code
12.5.7 Comparing Web Servers
Summary
Explorations Programming Exercises Projects
CHAPTER 13 Programming with Datagrams: A License Server
13.1 Software Control
13.2 A Brief History of License Control
13.3 A Noncomputer Example: Managing Company Cars

13.3.1 Description of Car Key Management
13.3.2 Managing Cars in Client/Server Terms
13.4 License Management
13.4.1 The License Server System: What Does It Do?
13.4.2 The License Server System: How Does It Work?
13.4.3 A Communication System
13.5 Datagram Sockets
13.5.1 Streams vs. Datagrams
13.5.2 Programming with Datagrams
13.5.3 Summary of sendto and recvfrom
13.5.4 Replying to Datagrams
13.5.5 Summary of Datagrams
13.6 License Server Version 1.0
13.6.1 Client Version 1
13.6.2 Server Version 1
13.6.3 Testing Version 1
13.6.4 How\'dWeDo?
13.7 Real-world Programming
13.7.1 Handling Client Crashes
13.7.2 Handling Server Crashes
13.7.3 Testing Version 2

13.8 Distributed License Servers
13.9 Unix Domain Sockets

13.9.1 Filenames as Socket Addresses
13.9.2 Programming with Unix Domain Sockets

xvi Table of Contents
13.10 Summary: Sockets and Servers Summary
Explorations
Programming Exercises
Projects
CHAPTER 14 Threads: Concurrent Functions
14.1 Doing Several Things at Once
14.2 Threads of Execution

14.2.1 A Single-Threaded Program
14.2.2 A Multithreaded Program
14.2.3 Function Summaries
14.3 Interthread Cooperation
14.3.1 Example 1: incrprint. c
14.3.2 Example 2: twordcount. c
14.3.3 Interthread Cooperation: Summary

14.4 Comparing Threads with Processes
14.5 Interthread Notification

14.5.1 Notifying Election Central
14.5.2 Programming with Condition Variables
14.5.3 Functions for Condition Variables
14.5.4 Back to the Web
14.6 A Threaded Web Server
14.6.1 Changes to Our Web Server
14.6.2 Threads Allow a New Feature
14.6.3 Preventing Zombie Threads: Detached Threads
14.6.4 The Code
14.7 Threads and Animation
14.7.1 Advantages of Threads
14.7.2 Threaded bounceld.c
14.7.3 Multiple Animations: tanimate. c
14.7.4 Mutexes and tanimate. c
14.7.5 A Thread for Curses
Summary
Explorations Programming Exercises
CHAPTER 15 IPC Roundup: Can We Talk?
15.1 Programming Choices
15.2 The talk Command: Reading from Multiple Inputs

15.2.1 Reading from Two File Descriptors at Once
15.2.2 The select System Call
15.2.3 select and talk
15.2.4 select vs. poll
15.3 Communication Choices
15.3.1 One Problem, Three Solutions
15.3.2 IPC with Files
15.3.3 Named Pipes
15.3.4 Shared Memory
15.3.5 Comparing Communication Methods
15.4 Interprocess Cooperation and Coordination
15.4.1 File Locks
15.4.2 Semaphores
15.4.3 Sockets and FIFOs vs. Shared Storage
15.5 A Print Spooler
15.5.1 Many Writers, One Reader
15.5.2 A Client/Server Model

15.6 IPC Overview
15.7 Connections and Games
Summary
Explorations Programming Exercises