Chapters 1 to 33

Copyediting is quite a bit more work than I expected! But, we've now passed halfway: Chapters 1 to 33 form the first four of eight logical parts of my book (see this earlier post). So, this is a good point to post the detailed table of contents so far. Here's the current table of contents for these chapters.

1 History and Standards [~20 pages]
1.1 A Brief History of Unix and C
1.2 A Brief History of Linux
        1.2.1 The GNU Project
        1.2.2 The Linux Kernel
1.3 Standardization
        1.3.1 The C Programming Language
        1.3.2 The First POSIX Standards
        1.3.3 X/Open Company and The Open Group
        1.3.4 SUSv3 and POSIX.1-2001
        1.3.5 SUSv4 and POSIX.1-2008
        1.3.6 Unix Standards Timeline
        1.3.7 Implementation Standards
        1.3.8 Linux, Standards, and the Linux Standard Base
1.4 Summary

2 Fundamental Concepts [~20 pages]
2.1 The Core Operating System: The Kernel
2.2 The Shell
2.3 Users and Groups
2.4 Single Directory Hierarchy, Directories, Links, and Files
2.5 File I/O Model
2.6 Programs
2.7 Processes
2.8 Memory Mappings
2.9 Static and Shared Libraries
2.10 Interprocess Communication and Synchronization
2.11 Signals
2.12 Threads
2.13 Process Groups and Shell Job Control
2.14 Sessions, Controlling Terminals, and Controlling Processes
2.15 Pseudoterminals
2.16 Date and Time
2.17 Client-server Architecture
2.18 Realtime
2.19 The /proc File System
2.20 Summary

3 System Programming Concepts [~25 pages]
3.1 System Calls
3.2 Library Functions
3.3 The Standard C Library; The GNU C Library (glibc)
3.4 Handling Errors from System Calls and Library Functions
3.5 Notes on the Example Programs in This Book
        3.5.1 Command-line Options and Arguments
        3.5.2 Common Functions and Header Files
3.6 Portability Issues
        3.6.1 Feature Test Macros
        3.6.2 System Data Types
        3.6.3 Miscellaneous Portability Issues
3.7 Summary
3.8 Exercises

4 File I/O: The Universal I/O Model [~20 pages]
4.1 Overview
4.2 Universality of I/O
4.3 Opening a File: open()
4.4 Reading from a File: read()
4.5 Writing to a File: write()
4.6 Closing a File: close()
4.7 Changing the Current File Offset: lseek()
4.8 Operations Outside the Universal I/O Model: ioctl()
4.9 Summary
4.10 Exercises

5 File I/O: Further Details [~25 pages]
5.1 Atomicity and Race Conditions
5.2 File Control Operations: fcntl()
5.3 Open File Status Flags
5.4 Relationship Between File Descriptors and Open Files
5.5 Duplicating File Descriptors
5.6 File I/O at a Specified Offset: pread() and pwrite()
5.7 Scatter-gather I/O: readv() and writev()
5.8 Truncating a File: truncate() and ftruncate()
5.9 Nonblocking I/O
5.10 I/O on Large Files
5.11 The /dev/fd Directory
5.12 Creating Temporary Files
5.13 Summary
5.14 Exercises

6 Processes [~25 pages]
6.1 Processes and Programs
6.2 Process ID and Parent Process ID
6.3 Memory Layout of a Process
6.4 Virtual Memory Management
6.5 The Stack and Stack Frames
6.6 Command-line Arguments (argc, argv)
6.7 Environment List
6.8 Performing a Nonlocal Goto: setjmp() and longjmp()
6.9 Summary
6.10 Exercises

7 Memory Allocation [~15 pages]
7.1 Allocating Memory on the Heap
        7.1.1 Adjusting the Program Break: brk() and sbrk()
        7.1.2 Allocating Memory on the Heap: malloc() and free()
        7.1.3 Implementation of malloc() and free()
        7.1.4 Other Methods of Allocating Memory on the Heap
7.2 Allocating Memory on the Stack: alloca()
7.3 Summary
7.4 Exercises

8 Users and Groups [~15 pages]
8.1 The Password File: /etc/passwd
8.2 The Shadow Password File: /etc/shadow
8.3 The Group File: /etc/group
8.4 Retrieving User and Group Information
8.5 Password Encryption and User Authentication
8.6 Summary
8.7 Exercises

9 Process Credentials [~20 pages]
9.1 Real User ID and Real Group ID
9.2 Effective User ID and Effective Group ID
9.3 Set-user-ID and Set-group-ID Programs
9.4 Saved Set-user-ID and Saved Set-group-ID
9.5 File System User ID and File System Group ID
9.6 Supplementary Group IDs
9.7 Retrieving and Modifying Process Credentials
        9.7.1 Retrieving and Modifying Real, Effective, and Saved Set IDs
        9.7.2 Retrieving and Modifying File System IDs
        9.7.3 Retrieving and Modifying Supplementary Group IDs
        9.7.4 Summary of Calls for Modifying Process Credentials
        9.7.5 Example: Displaying Process Credentials
9.8 Summary
9.9 Exercises

10 Times and Dates [~25 pages]
10.1 Calendar Time
10.2 Time-Conversion Functions
        10.2.1 Converting time_t to Printable Form
        10.2.2 Converting Between time_t and Broken-down Time
        10.2.3 Converting Between Broken-down Time and Printable Form
10.3 Timezones
10.4 Locales
10.5 Updating the System Clock
10.6 The Software Clock (Jiffies)
10.7 Process Time
10.8 Summary
10.9 Exercises

11 System Limits and Options [~10 pages]
11.1 System Limits
11.2 Retrieving System Limits (and Options) at Run Time
11.3 Retrieving File-related Limits (and Options) at Run Time
11.4 Indeterminate Limits
11.5 System Options
11.6 Summary
11.7 Exercises

12 System and Process Information [~10 pages]
12.1 The /proc File System
        12.1.1 Obtaining Information about a Process: /proc/PID
        12.1.2 System Information under /proc
        12.1.3 Accessing /proc Files
12.2 System Identification: uname()
12.3 Summary
12.4 Exercises

13 File I/O Buffering [~20 pages]
13.1 Kernel Buffering of File I/O: The Buffer Cache
13.2 Buffering in the stdio Library
13.3 Controlling Kernel Buffering of File I/O
13.4 Summary of I/O Buffering
13.5 Giving the Kernel Hints about I/O Patterns: posix_fadvise()
13.6 Bypassing the Buffer Cache: Direct I/O
13.7 Mixing Library Functions and System Calls for File I/O
13.8 Summary
13.9 Exercises

14 File Systems [~30 pages]
14.1 Device Special Files (Devices)
14.2 Disks and Partitions
14.3 File Systems
14.4 I-nodes
14.5 The Virtual File System (VFS)
14.6 Journaling File Systems
14.7 Single Directory Hierarchy and Mount Points
14.8 Mounting and Unmounting File Systems
14.8.1 Mounting a File System: mount()
14.8.2 Unmounting a File System: umount() and umount2()
14.9 Advanced Mount Features
14.9.1 Mounting a File System at Multiple Mount Points
14.9.2 Stacking Multiple Mounts on the Same Mount Point
14.9.3 Mount Flags That Are Per-mount Options
14.9.4 Bind Mounts
14.9.5 Recursive Bind Mounts
14.10 A Virtual Memory File System: tmpfs
14.11 Obtaining Information about a File System: statvfs()
14.12 Summary
14.13 Exercises

15 File Attributes [~30 pages]
15.1 Retrieving File Information: stat()
15.2 File Timestamps
        15.2.1 Changing File Timestamps with utime() and utimes()
        15.2.2 Changing File Timestamps with utimensat() and futimens()
15.3 File Ownership
        15.3.1 Ownership of New Files
        15.3.2 Changing File Ownership: chown(), fchown(), and lchown()
15.4 File Permissions
        15.4.1 Permissions on Regular Files
        15.4.2 Permissions on Directories
        15.4.3 Permission Checking Algorithm
        15.4.4 Checking File Accessibility: access()
        15.4.5 Set-user-ID, Set-group-ID, and Sticky Bits
        15.4.6 The Process File Mode Creation Mask: umask()
        15.4.7 Changing File Permissions: chmod() and fchmod()
15.5 I-node Flags (ext2 Extended File Attributes)
15.6 Summary
15.7 Exercises

16 Extended Attributes [~8 pages]
16.1 Overview
16.2 Extended Attribute Implementation Details
16.3 System Calls for Manipulating Extended Attributes
16.4 Summary
16.5 Exercises

17 Access Control Lists [~20 pages]
17.1 Overview
17.2 ACL Permission-Checking Algorithm
17.3 Long and Short Text Forms for ACLs
17.4 The ACL_MASK Entry and the ACL Group Class
17.5 The getfacl and setfacl Commands
17.6 Default ACLs and File Creation
17.7 ACL Implementation Limits
17.8 The ACL API
17.9 Summary
17.10 Exercises

18 Directories and Links [~35 pages]
18.1 Directories and (Hard) Links
18.2 Symbolic (Soft) Links
18.3 Creating and Removing (Hard) Links: link() and unlink()
18.4 Changing the Name of a File: rename()
18.5 Working with Symbolic Links: symlink() and readlink()
18.6 Creating and Removing Directories: mkdir() and rmdir()
18.7 Removing a File or Directory: remove()
18.8 Reading Directories: opendir() and readdir()
18.9 File Tree Walking: nftw()
18.10 The Current Working Directory of a Process
18.11 Operating Relative to a Directory File Descriptor
18.12 Changing the Root Directory of a Process: chroot()
18.13 Resolving a Pathname: realpath()
18.14 Parsing Pathname Strings: dirname() and basename()
18.15 Summary
18.16 Exercises

19 Monitoring File Events [~12 pages]
19.1 Overview
19.2 The inotify API
19.3 inotify Events
19.4 Reading inotify Events
19.5 Queue Limits and /proc Files
19.6 An Older System for Monitoring File Events: dnotify
19.7 Summary
19.8 Exercises

20 Signals: Fundamental Concepts [~30 pages]
20.1 Concepts and Overview
20.2 Signal Types and Default Actions
20.3 Changing Signal Dispositions: signal()
20.4 Introduction to Signal Handlers
20.5 Sending Signals: kill()
20.6 Checking for the Existence of a Process
20.7 Other Ways of Sending Signals: raise() and killpg()
20.8 Displaying Signal Descriptions
20.9 Signal Sets
20.10 The Signal Mask (Blocking Signal Delivery)
20.11 Pending Signals
20.12 Signals Are Not Queued
20.13 Changing Signal Dispositions: sigaction()
20.14 Waiting for a Signal: pause()
20.15 Summary
20.16 Exercises

21 Signals: Signal Handlers [~25 pages]
21.1 Designing Signal Handlers
        21.1.1 Signals Are Not Queued (Revisited)
        21.1.2 Reentrant and Async-signal-safe Functions
        21.1.3 Global Variables and the sig_atomic_t Data Type
21.2 Other Methods of Terminating a Signal Handler
        21.2.1 Performing a Nonlocal Goto from a Signal Handler
        21.2.2 Terminating a Process Abnormally: abort()
21.3 Handling a Signal on an Alternate Stack: sigaltstack()
21.4 The SA_SIGINFO Flag
21.5 Interruption and Restarting of System Calls
21.6 Summary
21.7 Exercises

22 Signals: Advanced Features [~30 pages]
22.1 Core Dump Files
22.2 Special Cases for Signal Delivery, Disposition, and Handling
22.3 Interruptible and Uninterruptible Process Sleep States
22.4 Hardware-generated Signals
22.5 Synchronous and Asynchronous Signal Generation
22.6 Timing and Order of Signal Delivery
22.7 Implementation and Portability of signal()
22.8 Realtime Signals
        22.8.1 Sending Realtime Signals
        22.8.2 Handling Realtime Signals
22.9 Waiting for a Signal Using a Mask: sigsuspend()
22.10 Synchronously Waiting for a Signal
22.11 Fetching Signals via a File Descriptor
22.12 Interprocess Communication with Signals
22.13 Earlier Signal APIs (System V and BSD)
22.14 Summary
22.15 Exercises

23 Timers and Sleeping [~30 pages]
23.1 Interval Timers
23.2 Scheduling and Accuracy of Timers
23.3 Setting Timeouts on Blocking Operations
23.4 Suspending Execution for a Fixed Interval (Sleeping)
        23.4.1 Low-resolution Sleeping: sleep()
        23.4.2 High-resolution Sleeping: nanosleep()
23.5 POSIX Clocks
        23.5.1 Retrieving the Value of a Clock: timer_gettime()
        23.5.2 Updating the Value of a Clock: timer_gettime()
        23.5.3 Obtaining the Clock ID of a Specific Process or Thread
        23.5.4 Improved High-resolution Sleeping: clock_nanosleep()
23.6 POSIX Interval Timers
        23.6.1 Creating a Timer: timer_create()
        23.6.2 Arming and Disarming a Timer: timer_settime()
        23.6.3 Retrieving the Current Value of a Timer: timer_gettime()
        23.6.4 Deleting a Timer: timer_delete()
        23.6.5 Notification via a Signal (SIGEV_SIGNAL)
        23.6.6 Timer Overruns
        23.6.7 Notification via a Thread (SIGEV_THREAD)
23.7 Timers That Notify via File Descriptors: the timerfd API
23.8 Summary
23.9 Exercises

24 Process Creation [~20 pages]
24.1 Overview of fork(), exit(), wait(), and execve()
24.2 Creating a New Process: fork()
        24.2.1 File Sharing Between Parent and Child
        24.2.2 Memory Semantics of fork()
24.3 The vfork() System Call
24.4 Race Conditions after fork()
24.5 Avoiding Race Conditions by Synchronizing with Signals
24.6 Summary

25 Process Termination [~10 pages]
25.1 Terminating a Process: _exit() and exit()
25.2 Details of Process Termination
25.3 Exit Handlers
25.4 Interactions Between fork(), stdio Buffers, and _exit()
25.5 Summary
25.6 Exercises

26 Monitoring Child Processes [~20 pages]
26.1 Waiting on a Child Process
        26.1.1 The wait() System Call
        26.1.2 The waitpid() System Call
        26.1.3 The Wait Status Value
        26.1.4 Process Termination from a Signal Handler
        26.1.5 The waitid() System Call
        26.1.6 The wait3() and wait4() System Calls
26.2 Orphans and Zombies
26.3 The SIGCHLD Signal
        26.3.1 Establishing a Handler for SIGCHLD
        26.3.2 Delivery of SIGCHLD for Stopped Children
        26.3.3 Ignoring Dead Child Processes
26.4 Summary
26.5 Exercises

27 Program Execution [~20 pages]
27.1 Executing a New Program: execve()
27.2 The exec() Library Functions
        27.2.1 The PATH Environment Variable
        27.2.2 Specifying Program Arguments As a List
        27.2.3 Passing the Caller's Environment to the New Program
        27.2.4 Executing a File Referred to by a Descriptor: fexecve()
27.3 Interpreter Scripts
27.4 File Descriptors and exec()
27.5 Signals and exec()
27.6 Executing a Shell Command: system()
27.7 Implementing system()
27.8 Summary
27.9 Exercises

28 Process Creation and Program Execution in More Detail [~25 pages]
28.1 Process Accounting
28.2 The clone() System Call
        28.2.1 The clone() flags Argument
        28.2.2 Extensions to waitpid() for Cloned Children
28.3 Speed of Process Creation
28.4 Effect of exec() and fork() on Process Attributes
28.5 Summary
28.6 Exercises

29 Threads: Introduction [~15 pages]
29.1 Overview
29.2 Background Details of the Pthreads API
29.3 Thread Creation
29.4 Thread Termination
29.5 Thread IDs
29.6 Joining with a Terminated Thread: pthread_join()
29.7 Detaching a Thread: pthread_detach()
29.8 Thread Attributes
29.9 Threads Versus Processes
29.10 Summary
29.11 Exercises

30 Threads: Thread Synchronization [~25 pages]
30.1 Protecting Accesses to Shared Variables: Mutexes
        30.1.1 Statically Allocated Mutexes
        30.1.2 Locking and Unlocking a Mutex
        30.1.3 Performance of Mutexes
        30.1.4 Mutex Deadlocks
        30.1.5 Dynamically Initializing a Mutex
        30.1.6 Mutex Attributes
        30.1.7 Mutex Types
30.2 Signaling Changes of State: Condition Variables
        30.2.1 Statically Allocated Condition Variables
        30.2.2 Signaling and Waiting on Condition Variables
        30.2.3 Testing a Condition Variable’s Predicate
        30.2.4 Example Program: Joining Any Terminated Thread
        30.2.5 Dynamically Allocated Condition Variables
30.3 Summary
30.4 Exercises

31 Threads: Thread Safety and Per-thread Storage [~15 pages]
31.1 Thread Safety (and Reentrancy Revisited)
31.2 One-time Initialization
31.3 Thread-specific Data
        31.3.1 Thread-specific Data from the Library Function’s Perspective
        31.3.2 Overview of the Thread-specific Data API
        31.3.3 Details of the Thread-specific Data API
        31.3.4 Employing the Thread-specific Data API
        31.3.5 Thread-specific Data Implementation Limits
31.4 Thread-local Storage
31.5 Summary
31.6 Exercises

32 Threads: Thread Cancellation [~10 pages]
32.1 Canceling a Thread
32.2 Cancellation State and Type
32.3 Cancellation Points
32.4 Testing for Thread Cancellation
32.5 Cleanup Handlers
32.6 Asynchronous Cancelability
32.7 Summary
32.8 Exercises

33 Threads: Further Details [~15 pages]
33.1 Thread Stacks
33.2 Threads and Signals
        33.2.1 How the Unix Signal Model Maps to Threads
        33.2.2 Manipulating the Thread Signal Mask
        33.2.3 Sending a Signal to a Thread
        33.2.4 Dealing with Asynchronous Signals Sanely
33.3 Threads and Process Control
33.4 Thread Implementation Models
33.5 Linux Implementations of POSIX Threads
        33.5.1 LinuxThreads
        33.5.2 NPTL
        33.5.3 Which Threading Implementation?
33.6 Advanced Features of the Pthreads API
33.7 Summary
33.8 Exercises


  1. very nice so far :-)
    I've also been reading you're previous post about the book, and I must say that 64 chapters is quite an impressive number.

    I'am really curious about one thing: how will your book compare to NP1,2 and APUE from Stevens (the reference so far, at least for me) ?
    Sorry to ask that :-/, but you will cover as much ground as he did (actually more since some stuff like fs notifications were not covered by Stevens), so: what differences do see regarding your work and Stevens work ?
    Will these materials be covered inthe same manner ?

    Anyhow, cannot wait for your book, we've been missing a good book in system programming for a long time.

    -- paulo

  2. @vodoom: I do provide a substantial grounding in network programming in my book, but there's no question that UNP v1 and v2 are going to remain the definitive works for network programming. With respect to APUE: my book provides Linux-specific details not in APUE, covers a broader range of topics (some of which are in UNPv2, but not in APUE), and is more current with respect to standards (I cover up to and including POSIX.1-2008/SUSv4). So, I cover more ground than APUE, and probably to a similar depth. On the other hand, in terms of sheer quality of writing, APUE is a tough act to follow; I've tried to get close. In terms of general approach, I think there's a fair amount of similarity between my approach and APUE: give a good overview of each topic, drill down into specifics, and provide a working example. It's a good formula. You might also find it worth reading my latest post today, on the subject of choosing a title for my book.