You are previewing Linux Application Development, Second Edition.
O'Reilly logo
Linux Application Development, Second Edition

Book Description

"The first edition of this book has always been kept within arm's reach of my desk due to the wonderful explanations of all areas of the Linux userspace API. This second edition greatly overshadows the first one, and will replace it."
--Greg Kroah-Hartman, Linux kernel programmer

Develop Software that Leverages the Full Power of Today's Linux

Linux Application Development, Second Edition, is the definitive reference for Linux programmers at all levels of experience, including C programmers moving from other operating systems. Building on their widely praised first edition, leading Linux programmers Michael Johnson and Erik Troan systematically present the key APIs and techniques you need to create robust, secure, efficient software or to port existing code to Linux.

This book has been fully updated for the Linux 2.6 kernel, GNU C library version 2.3, the latest POSIX standards, and the Single Unix Specification, Issue 6. Its deep coverage of Linux-specific extensions and features helps you take advantage of the full power of contemporary Linux. Along the way, the authors share insights, tips, and tricks for developers working with any recent Linux distribution, and virtually any version of Unix.

Topics include

  • Developing in Linux: understanding the operating system, licensing,

  • and documentation

  • The development environment: compilers, linker and loader, and unique

  • debugging tools

  • System programming: process models, file handling, signal processing, directory operations, and job control

  • Terminals, sockets, timers, virtual consoles, and the Linux console

  • Development libraries: string matching, terminal handling, command-line parsing, authentication, and more

  • Hundreds of downloadable code samples

  • New to this edition

  • The GNU C library (glibc), underlying standards, and test macros

  • Writing secure Linux programs, system daemons, and utilities

  • Significantly expanded coverage of memory debugging, including Valgrind and mpr

  • Greatly improved coverage of regular expressions

  • IPv6 networking coverage, including new system library interfaces for using IPv6 and IPv4 interchangeably

  • Coverage of strace, ltrace, real-time signals, poll and epoll system calls, popt library improvements, Pluggable Authentication Modules (PAM), qdbm, and much more

  • Improved index and glossary, plus line-numbered code examples



  • Table of Contents

    1. Copyright
      1. Dedication
    2. List of Tables
    3. Code Examples
    4. Preface
      1. Second Edition
      2. Acknowledgments
    5. 1. Getting Started
      1. 1. History of Linux Development
        1. 1.1. A Short History of Free Unix Software
        2. 1.2. Development of Linux
        3. 1.3. Notional Lineage of Unix Systems
        4. 1.4. Linux Lineage
      2. 2. Licenses and Copyright
        1. 2.1. Copyright
        2. 2.2. Licensing
        3. 2.3. Free Software Licenses
          1. 2.3.1. The GNU General Public License
          2. 2.3.2. The GNU Library General Public License
          3. 2.3.3. MIT/X/BSD-Style Licenses
          4. 2.3.4. Old BSD-Style Licenses
          5. 2.3.5. Artistic License
          6. 2.3.6. License Incompatibilities
      3. 3. Online System Documentation
        1. 3.1. The man Pages
        2. 3.2. The Info Pages
        3. 3.3. Other Documentation
    6. 2. Development Tools and Environment
      1. 4. Development Tools
        1. 4.1. Editors
          1. 4.1.1. Emacs
          2. 4.1.2. vi
        2. 4.2. Make
          1. 4.2.1. Complex Command Lines
          2. 4.2.2. Variables
          3. 4.2.3. Suffix Rules
        3. 4.3. The GNU Debugger
        4. 4.4. Tracing Program Actions
      2. 5. gcc Options and Extensions
        1. 5.1. gcc Options
        2. 5.2. Header Files
          1. 5.2.1. long long
          2. 5.2.2. Inline Functions
          3. 5.2.3. Alternative Extended Keywords
          4. 5.2.4. Attributes
      3. 6. The GNU C Library
        1. 6.1. Feature Selection
        2. 6.2. POSIX Interfaces
          1. 6.2.1. POSIX Required Types
          2. 6.2.2. Discovering Run-Time Capabilities
          3. 6.2.3. Finding and Setting Basic System Information
        3. 6.3. Compatibility
      4. 7. Memory Debugging Tools
        1. 7.1. Buggy Code
        2. 7.2. Memory-Checking Tools Included in glibc
          1. 7.2.1. Finding Memory Heap Corruption
          2. 7.2.2. Using mtrace() to Track Allocations
        3. 7.3. Finding Memory Leaks with mpr
        4. 7.4. Investigating Memory Errors with Valgrind
        5. 7.5. Electric Fence
          1. 7.5.1. Using Electric Fence
          2. 7.5.2. Memory Alignment
          3. 7.5.3. Other Features
          4. 7.5.4. Limitations
          5. 7.5.5. Resource Consumption
      5. 8. Creating and Using Libraries
        1. 8.1. Static Libraries
        2. 8.2. Shared Libraries
        3. 8.3. Designing Shared Libraries
          1. 8.3.1. Managing Compatibility
          2. 8.3.2. Incompatible Libraries
          3. 8.3.3. Designing Compatible Libraries
        4. 8.4. Building Shared Libraries
        5. 8.5. Installing Shared Libraries
          1. 8.5.1. Example
        6. 8.6. Using Shared Libraries
          1. 8.6.1. Using Noninstalled Libraries
          2. 8.6.2. Preloading Libraries
      6. 9. Linux System Environment
        1. 9.1. The Process Environment
        2. 9.2. Understanding System Calls
          1. 9.2.1. System Call Limitations
          2. 9.2.2. System Call Return Codes
          3. 9.2.3. Using System Calls
          4. 9.2.4. Common Error Return Codes
        3. 9.3. Finding Header and Library Files
    7. 3. System Programming
      1. 10. The Process Model
        1. 10.1. Defining a Process
          1. 10.1.1. Complicating Things with Threads
          2. 10.1.2. The Linux Approach
        2. 10.2. Process Attributes
          1. 10.2.1. The pid and Parentage
          2. 10.2.2. Credentials
          3. 10.2.3. The filesystem uid
          4. 10.2.4. User and Group ID Summary
        3. 10.3. Process Information
          1. 10.3.1. Program Arguments
          2. 10.3.2. Resource Usage
          3. 10.3.3. Establishing Usage Limits
        4. 10.4. Process Primitives
          1. 10.4.1. Having Children
          2. 10.4.2. Watching Your Children Die
          3. 10.4.3. Running New Programs
          4. 10.4.4. Faster Process Creation with vfork()
          5. 10.4.5. Killing Yourself
          6. 10.4.6. Killing Others
          7. 10.4.7. Dumping Core
        5. 10.5. Simple Children
          1. 10.5.1. Running and Waiting with system()
          2. 10.5.2. Reading or Writing from a Process
        6. 10.6. Sessions and Process Groups
          1. 10.6.1. Sessions
          2. 10.6.2. Controlling Terminal
          3. 10.6.3. Process Groups
          4. 10.6.4. Orphaned Process Groups
        7. 10.7. Introduction to ladsh
          1. 10.7.1. Running External Programs with ladsh
        8. 10.8. Creating Clones
      2. 11. Simple File Handling
        1. 11.1. The File Mode
          1. 11.1.1. File Access Permissions
          2. 11.1.2. File Permission Modifiers
          3. 11.1.3. File Types
          4. 11.1.4. The Process’s umask
        2. 11.2. Basic File Operations
          1. 11.2.1. File Descriptors
          2. 11.2.2. Closing Files
          3. 11.2.3. Opening Files in the File System
          4. 11.2.4. Reading, Writing, and Moving Around
          5. 11.2.5. Partial Reads and Writes
          6. 11.2.6. Shortening Files
          7. 11.2.7. Synchronizing Files
          8. 11.2.8. Other Operations
        3. 11.3. Querying and Changing Inode Information
          1. 11.3.1. Finding Inode Information
          2. 11.3.2. A Simple Example of stat()
          3. 11.3.3. Easily Determining Access Rights
          4. 11.3.4. Changing a File’s Access Permissions
          5. 11.3.5. Changing a File’s Owner and Group
          6. 11.3.6. Changing a File’s Timestamps
          7. 11.3.7. Ext3 Extended Attributes
        4. 11.4. Manipulating Directory Entries
          1. 11.4.1. Creating Device and Named Pipe Entries
          2. 11.4.2. Creating Hard Links
          3. 11.4.3. Using Symbolic Links
          4. 11.4.4. Removing Files
          5. 11.4.5. Renaming Files
        5. 11.5. Manipulating File Descriptors
          1. 11.5.1. Changing the Access Mode for an Open File
          2. 11.5.2. Modifiying the close-on-exec Flag
          3. 11.5.3. Duplicating File Descriptors
        6. 11.6. Creating Unnamed Pipes
        7. 11.7. Adding Redirection to ladsh
          1. 11.7.1. The Data Structures
          2. 11.7.2. Changing the Code
      3. 12. Signal Processing
        1. 12.1. Signal Concepts
          1. 12.1.1. Life Cycle of a Signal
          2. 12.1.2. Simple Signals
          3. 12.1.3. Reliable Signals
          4. 12.1.4. Signals and System Calls
        2. 12.2. The Linux (and POSIX) Signal API
          1. 12.2.1. Sending Signals
          2. 12.2.2. Using sigset_t
          3. 12.2.3. Catching Signals
          4. 12.2.4. Manipulating a Process’s Signal Mask
          5. 12.2.5. Finding the Set of Pending Signals
          6. 12.2.6. Waiting for Signals
        3. 12.3. Available Signals
          1. 12.3.1. Describing Signals
        4. 12.4. Writing Signal Handlers
        5. 12.5. Reopening Log Files
        6. 12.6. Real-Time Signals
          1. 12.6.1. Signal Queueing and Ordering
        7. 12.7. Learning About a Signal
          1. 12.7.1. Getting a Signal’s Context
          2. 12.7.2. Sending Data with a Signal
      4. 13. Advanced File Handling
        1. 13.1. Input and Output Multiplexing
          1. 13.1.1. Nonblocking I/O
          2. 13.1.2. Multiplexing with poll()
          3. 13.1.3. Multiplexing with select()
          4. 13.1.4. Comparing poll() and select()
          5. 13.1.5. Multiplexing with epoll
          6. 13.1.6. Comparing poll() and epoll
        2. 13.2. Memory Mapping
          1. 13.2.1. Page Alignment
          2. 13.2.2. Establishing Memory Mappings
          3. 13.2.3. Unmapping Regions
          4. 13.2.4. Syncing Memory Regions to Disk
          5. 13.2.5. Locking Memory Regions
        3. 13.3. File Locking
          1. 13.3.1. Lock Files
          2. 13.3.2. Record Locking
          3. 13.3.3. Mandatory Locks
          4. 13.3.4. Leasing a File
        4. 13.4. Alternatives to read() and write()
          1. 13.4.1. Scatter/Gather Reads and Writes
          2. 13.4.2. Ignoring the File Pointer
      5. 14. Directory Operations
        1. 14.1. The Current Working Directory
          1. 14.1.1. Finding the Current Working Directory
          2. 14.1.2. The . and .. Special Files
          3. 14.1.3. Changing the Current Directory
        2. 14.2. Changing the Root Directory
        3. 14.3. Creating and Removing Directories
          1. 14.3.1. Creating New Directories
          2. 14.3.2. Removing Directories
        4. 14.4. Reading a Directory’s Contents
          1. 14.4.1. Starting Over
        5. 14.5. File Name Globbing
          1. 14.5.1. Use a Subprocess
          2. 14.5.2. Internal Globbing
        6. 14.6. Adding Directories and Globbing to ladsh
          1. 14.6.1. Adding cd and pwd
          2. 14.6.2. Adding File Name Globbing
        7. 14.7. Walking File System Trees
          1. 14.7.1. Using ftw()
          2. 14.7.2. File Tree Walks with nftw()
          3. 14.7.3. Implementing find
        8. 14.8. Directory Change Notification
      6. 15. Job Control
        1. 15.1. Job Control Basics
          1. 15.1.1. Restarting Processes
          2. 15.1.2. Stopping Processes
          3. 15.1.3. Handling Job Control Signals
        2. 15.2. Job Control in ladsh
      7. 16. Terminals and Pseudo Terminals
        1. 16.1. tty Operations
          1. 16.1.1. Terminal Utility Functions
          2. 16.1.2. Controlling Terminals
          3. 16.1.3. Terminal Ownership
          4. 16.1.4. Recording with utempter
          5. 16.1.5. Recording by Hand
        2. 16.2. termios Overview
        3. 16.3. termios Examples
          1. 16.3.1. Passwords
          2. 16.3.2. Serial Communications
        4. 16.4. termios Debugging
        5. 16.5. termios Reference
          1. 16.5.1. Functions
          2. 16.5.2. Window Sizes
          3. 16.5.3. Flags
          4. 16.5.4. Input Flags
          5. 16.5.5. Output Flags
          6. 16.5.6. Control Flags
          7. 16.5.7. Control Characters
          8. 16.5.8. Local Flags
          9. 16.5.9. Controlling read()
        6. 16.6. Pseudo ttys
          1. 16.6.1. Opening Pseudo ttys
          2. 16.6.2. Opening Pseudo ttys the Easy Ways
          3. 16.6.3. Opening Pseudo ttys the Hard Ways
          4. 16.6.4. Pseudo tty Examples
      8. 17. Networking with Sockets
        1. 17.1. Protocol Support
          1. 17.1.1. Nice Networking
          2. 17.1.2. Real Networking
          3. 17.1.3. Making Reality Play Nice
          4. 17.1.4. Addresses
        2. 17.2. Utility Functions
        3. 17.3. Basic Socket Operations
          1. 17.3.1. Creating a Socket
          2. 17.3.2. Establishing Connections
          3. 17.3.3. Binding an Address to a Socket
          4. 17.3.4. Waiting for Connections
          5. 17.3.5. Connecting to a Server
          6. 17.3.6. Finding Connection Addresses
        4. 17.4. Unix Domain Sockets
          1. 17.4.1. Unix Domain Addresses
          2. 17.4.2. Waiting for a Connection
          3. 17.4.3. Connecting to a Server
          4. 17.4.4. Running the Unix Domain Examples
          5. 17.4.5. Unnamed Unix Domain Sockets
          6. 17.4.6. Passing File Descriptors
        5. 17.5. Networking Machines with TCP/IP
          1. 17.5.1. Byte Ordering
          2. 17.5.2. IPv4 Addressing
          3. 17.5.3. IPv6 Addressing
          4. 17.5.4. Manipulating IP Addresses
          5. 17.5.5. Turning Names into Addresses
          6. 17.5.6. Turning Addresses into Names
          7. 17.5.7. Listening for TCP Connections
          8. 17.5.8. TCP Client Applications
        6. 17.6. Using UDP Datagrams
          1. 17.6.1. Creating a UDP Socket
          2. 17.6.2. Sending and Receiving Datagrams
          3. 17.6.3. A Simple tftp Server
        7. 17.7. Socket Errors
        8. 17.8. Legacy Networking Functions
          1. 17.8.1. IPv4 Address Manipulation
          2. 17.8.2. Hostname Resolution
          3. 17.8.3. Legacy Host Information Lookup Example
          4. 17.8.4. Looking Up Port Numbers
      9. 18. Time
        1. 18.1. Telling Time and Dates
          1. 18.1.1. Representing Time
          2. 18.1.2. Converting, Formatting, and Parsing Times
          3. 18.1.3. The Limits of Time
        2. 18.2. Using Timers
          1. 18.2.1. Sleeping
          2. 18.2.2. Interval Timers
      10. 19. Random Numbers
        1. 19.1. Pseudo-Random Numbers
        2. 19.2. Cryptography and Random Numbers
      11. 20. Programming Virtual Consoles
        1. 20.1. Getting Started
        2. 20.2. Beeping
        3. 20.3. Determining Whether the Terminal Is a VC
        4. 20.4. Finding the Current VC
        5. 20.5. Managing VC Switching
        6. 20.6. Example: The open Command
      12. 21. The Linux Console
        1. 21.1. Capability Databases
        2. 21.2. Glyphs, Characters, and Maps
        3. 21.3. Linux Console Capabilities
          1. 21.3.1. Control Characters
          2. 21.3.2. Escape Sequences
          3. 21.3.3. Testing Sequences
          4. 21.3.4. Complex Escape Sequences
        4. 21.4. Direct Screen Writing
      13. 22. Writing Secure Programs
        1. 22.1. When Security Matters
          1. 22.1.1. When Security Fails
        2. 22.2. Minimizing the Opportunity for Attack
          1. 22.2.1. Giving Up Permissions
          2. 22.2.2. Getting a Helping Hand
          3. 22.2.3. Restricting File System Access
        3. 22.3. Common Security Holes
          1. 22.3.1. Buffer Overflows
          2. 22.3.2. Parsing Filenames
          3. 22.3.3. Environment Variables
          4. 22.3.4. Running the Shell
          5. 22.3.5. Creating Temporary Files
          6. 22.3.6. Race Conditions and Signal Handlers
          7. 22.3.7. Closing File Descriptors
        4. 22.4. Running as a Daemon
    8. 4. Development Libraries
      1. 23. String Matching
        1. 23.1. Globbing Arbitrary Strings
        2. 23.2. Regular Expressions
          1. 23.2.1. Linux Regular Expressions
          2. 23.2.2. Regular Expression Matching
          3. 23.2.3. A Simple grep
      2. 24. Terminal Handling with S-Lang
        1. 24.1. Input Handling
          1. 24.1.1. Initializing S-Lang Input Handling
          2. 24.1.2. Restoring the Terminal State
          3. 24.1.3. Reading Characters from the Terminal
          4. 24.1.4. Checking for Pending Input
        2. 24.2. Output Handling
          1. 24.2.1. Initializing Screen Management
          2. 24.2.2. Updating the Display
          3. 24.2.3. Moving the Cursor
          4. 24.2.4. Finishing Screen Management
          5. 24.2.5. Skeleton Screen Management
          6. 24.2.6. Switching Character Sets
          7. 24.2.7. Writing to the Screen
          8. 24.2.8. Drawing Lines and Boxes
          9. 24.2.9. Using Color
      3. 25. A Hashed Database Library
        1. 25.1. Overview
        2. 25.2. Basic Operations
          1. 25.2.1. Opening a qdbm File
          2. 25.2.2. Closing a Database
          3. 25.2.3. Obtaining the File Descriptor
          4. 25.2.4. Syncing the Database
        3. 25.3. Reading Records
          1. 25.3.1. Reading a Particular Record
          2. 25.3.2. Reading Records Sequentially
        4. 25.4. Modifying the Database
          1. 25.4.1. Adding Records
          2. 25.4.2. Removing Records
        5. 25.5. Example
      4. 26. Parsing Command-Line Options
        1. 26.1. The Option Table
          1. 26.1.1. Defining the Options
          2. 26.1.2. Nesting Option Tables
        2. 26.2. Using the Option Table
          1. 26.2.1. Creating a Context
          2. 26.2.2. Parsing the Command Line
          3. 26.2.3. Leftover Arguments
          4. 26.2.4. Automatic Help Messages
        3. 26.3. Using Callbacks
        4. 26.4. Error Handling
        5. 26.5. Option Aliasing
          1. 26.5.1. Specifying Aliases
          2. 26.5.2. Enabling Aliases
        6. 26.6. Parsing Argument Strings
        7. 26.7. Handling Extra Arguments
        8. 26.8. Sample Application
      5. 27. Dynamic Loading at Run Time
        1. 27.1. The dl Interface
          1. 27.1.1. Example
      6. 28. User Identification and Authentication
        1. 28.1. ID-to-Name Translation
          1. 28.1.1. Example: The id Command
        2. 28.2. Pluggable Authentication Modules
          1. 28.2.1. PAM Conversations
          2. 28.2.2. PAM Actions
    9. Appendices
      1. A. Header Files
      2. B. ladsh Source Code
    10. Glossary
    11. Bibliography