| Chapter 3 | | Utility Functions | 59 |
| 3.1 | | Introduction | 59 |
| 3.2 | | Manipulating Character Classes | 60 |
| | 3.2.1 Testing Character Class Membership | 60 |
| | 3.2.2 Changing Character Class Membership | 63 |
| | 3.2.3 Summary of Character Classes | 64 |
| 3.3 | | Manipulating Character Strings | 65 |
| | 3.3.1 Finding the Length of a String | 66 |
| | 3.3.2 Comparing Strings | 67 |
| | 3.3.3 String Concatenation | 71 |
| | 3.3.4 Copying Strings | 73 |
| | 3.3.5 String Searching Functions | 74 |
| | 3.3.6 Duplicating Strings | 80 |
| | 3.3.7 Splitting a String into Tokens | 81 |
| | 3.3.8 Functions for Transforming Strings | 84 |
| | 3.3.9 Converting Strings to Numbers | 87 |
| | 3.3.10 Converting Numbers to Strings | 91 |
| 3.4 | | Manipulating Byte Arrays | 91 |
| | 3.4.1 Comparing Byte Arrays | 92 |
| | 3.4.2 Copying Byte Arrays | 92 |
| | 3.4.3 Searching Byte Arrays | 93 |
| | 3.4.4 Initializing Byte Arrays | 94 |
| 3.5 | | Dynamic Memory | 94 |
| | 3.5.1 Memory Alignment | 94 |
| | 3.5.2 Allocating Dynamic Memory | 96 |
| | 3.5.3 Freeing Dynamic Memory | 99 |
| 3.6 | | Dynamic Memory | 100 |
| | 3.6.1 The malloc Library | 100 |
| | 3.6.2 The bsdmalloc Library | 102 |
| | 3.6.3 The mapmalloc Library | 103 |
| | 3.6.4 The watchmalloc Shared Object | 103 |
| | 3.6.5 Comparing the malloc Libraries | 106 |
| 3.7 | | Temporary Files | 108 |
| | 3.7.1 Generating Temporary Filenames | 108 |
| | 3.7.2 Creating Temporary Files | 109 |
| 3.8 | | Parsing Command Line Arguments | 110 |
| 3.9 | | Error Reporting | 117 |
| 3.10 | | Suspending a Process | 119 |
| 3.11 | | Summary | 120 |
|
| Chapter 4 | | Basic File I/O | 123 |
| 4.1 | | Introduction | 123 |
| 4.2 | | File Descriptors | 123 |
| 4.3 | | The open Function | 124 |
| 4.4 | | The creat Function | 126 |
| 4.5 | | The close and closefrom Functions | 127 |
| 4.6 | | The lseek and llseek Functions | 128 |
| 4.7 | | The tell Function | 131 |
| 4.8 | | The read and pread Functions | 131 |
| 4.9 | | The write and pwrite Functions | 132 |
| 4.10 | | The readn and writen Functions | 134 |
| 4.11 | | I/O Efficiency | 135 |
| 4.12 | | File Sharing | 136 |
| 4.13 | | Atomic Operations | 139 |
| 4.14 | | The dup and dup2 Functions | 140 |
| 4.15 | | The fcntl Function | 142 |
| 4.16 | | The ioctl Function | 153 |
| 4.17 | | The fdwalk Function | 153 |
| 4.18 | | Direct I/O | 155 |
| 4.19 | | The /dev/fd File System | 156 |
| 4.20 | | Summary | 158 |
|
| Chapter 5 | | The Standard I/O Library | 159 |
| 5.1 | | Introduction | 159 |
| 5.2 | | File Streams, Data Types, and Constants | 159 |
| 5.3 | | Standard Input, Standard Output, and Standard Error | 160 |
| 5.4 | | Opening a File Stream | 161 |
| 5.5 | | Closing a File Stream | 163 |
| 5.6 | | Reading and Writing | 163 |
| | 5.6.1 Character Input Functions | 164 |
| | 5.6.2 Character Output Functions | 165 |
| | 5.6.3 Line Input Functions | 166 |
| | 5.6.4 Line Output Functions | 167 |
| | 5.6.5 Binary I/O | 167 |
| 5.7 | | Stream Status | 167 |
| 5.8 | | Formatted I/O | 170 |
| | 5.8.1 Formatted Output | 170 |
| | 5.8.2 Formatted Input | 172 |
| | 5.8.3 Format Conversion Specifications | 173 |
| | 5.8.4 C Language Escape Sequences | 183 |
| 5.9 | | Positioning a Stream | 184 |
| 5.10 | | File Stream Locking | 185 |
| | 5.10.1 Unlocked File Stream I/O | 189 |
| 5.11 | | Buffering | 191 |
| 5.12 | | Standard I/O Efficiency | 194 |
| 5.13 | | Summary | 199 |
|
| Chapter 6 | | Date and Time Operations | 201 |
| 6.1 | | Introduction | 201 |
| 6.2 | | The Complexities of Converting Time | 201 |
| 6.3 | | Getting the Current Time | 203 |
| | 6.3.1 The difftime Function | 205 |
| 6.4 | | Setting the Current Time | 205 |
| 6.5 | | Getting the Current Time Zone | 206 |
| 6.6 | | Converting between UNIX Time and Calendar Time | 207 |
| | 6.6.1 The localtime and localtime_r Functions | 209 |
| | 6.6.2 The gmtime and gmtime_r Functions | 210 |
| | 6.6.3 The mktime Function | 210 |
| 6.7 | | Formatted Date I/O | 212 |
| | 6.7.1 Converting a Date to a Formatted String | 213 |
| | 6.7.2 Converting a Formatted String to a Date | 217 |
| 6.8 | | Summary | 222 |
|
| Chapter 7 | | Users and Groups | 223 |
| 7.1 | | Introduction | 223 |
| 7.2 | | User Names | 223 |
| 7.3 | | User IDs | 227 |
| 7.4 | | Group IDs | 231 |
| 7.5 | | Group Membership | 234 |
| 7.6 | | The Password File | 237 |
| 7.7 | | The Shadow Password File | 243 |
| 7.8 | | Reading and Encrypting Passwords | 250 |
| 7.9 | | The Group File | 256 |
| 7.10 | | The utmpx and wtmpx Files | 261 |
| 7.11 | | The utmp and wtmp Files | 268 |
| 7.12 | | The lastlog File | 269 |
| 7.13 | | The shells File | 270 |
| 7.14 | | Summary | 273 |
|
| Chapter 8 | | System Information and Resource Limits | 275 |
| 8.1 | | Introduction | 275 |
| 8.2 | | System Information and Identification | 276 |
| 8.3 | | System Resource Limits | 282 |
| 8.4 | | Per-Process Resource Limits | 297 |
| 8.5 | | The Resource Control Facility | 302 |
| 8.6 | | Resource Control Examples | 311 |
| 8.7 | | Resource Usage Information | 319 |
| 8.8 | | Determining Resource Usage Using the /proc File System | 325 |
| 8.9 | | Determining the System's Load Average | 334 |
| 8.10 | | Summary | 335 |
|
| Chapter 9 | | Secure C Programming | 337 |
| 9.1 | | Introduction | 337 |
| 9.2 | | Buffer Overflows | 338 |
| 9.3 | | The Program's Environment | 339 |
| 9.4 | | Defensive Programming | 340 |
| 9.5 | | The Principle of Least Privilege | 340 |
| 9.6 | | Using chroot Jails | 344 |
| 9.7 | | Tips For Writing Secure Programs | 346 |
| 9.8 | | Summary | 349 |
| Program 1.1 | | List all the files in a directory | 9 |
| Program 1.2 | | Copy standard input to standard output using unbuffered I/O functions | 14 |
| Program 1.3 | | Copy standard input to standard output using standard I/O functions | 15 |
| Program 1.4 | | Print our process ID and parent process ID | 18 |
| Program 1.5 | | A very simple shell program | 19 |
| Program 1.6 | | Print our user and group IDs | 24 |
| Program 1.7 | | Our shell, modified to catch SIGINT | 26 |
| Program 1.8 | | Calculate the average system call latency | 29 |
| Program 1.9 | | Sign extension problems in 64-bit code | 38 |
| Program 1.10 | | Large file demonstration | 41 |
| Program 3.1 | | Showing the character class of a character | 65 |
| Program 3.2 | | Using strlen, strspn, and strcspn | 67 |
| Program 3.3 | | Bubble sort using strcmp | 69 |
| Program 3.4 | | Safe string concatenation | 72 |
| Program 3.5 | | Safe string copying | 75 |
| Program 3.6 | | Our highlight function | 76 |
| Program 3.7 | | Searching for the first occurrence of a character | 76 |
| Program 3.8 | | Find the first of several characters | 79 |
| Program 3.9 | | Searching for a substring | 80 |
| Program 3.10 | | Splitting lines into tokens | 82 |
| Program 3.11 | | Another method of splitting a line into tokens | 84 |
| Program 3.12 | | String encryption using rot13 | 86 |
| Program 3.13 | | Converting numbers using strtol | 89 |
| Program 3.14 | | Comparing the different versions of malloc | 107 |
| Program 3.15 | | Using getopt and getsubopt | 114 |
| Program 3.16 | | Using an assertion to check for a NULL pointer | 119 |
| Program 4.1 | | Creating a sparse file | 130 |
| Program 4.2 | | Copy a file using read and write | 133 |
| Program 4.3 | | Print file status flags | 148 |
| Program 4.4 | | Print out the file access mode and status flags | 149 |
| Program 4.5 | | Print the extended and regular file descriptor flags | 150 |
| Program 4.6 | | A function to set file flags | 151 |
| Program 4.7 | | Copy a file using synchronous writes | 152 |
| Program 4.8 | | Implementing the closefrom function | 154 |
| Program 4.9 | | Investigating how direct I/O affects sequential file I/O | 157 |
| Program 5.1 | | Simple conversion specifications | 178 |
| Program 5.2 | | Using the alternative conversion introducer | 178 |
| Program 5.3 | | Adding precision modifiers | 179 |
| Program 5.4 | | Adding conversion specification flags | 181 |
| Program 5.5 | | Adding size modifiers | 183 |
| Program 5.6 | | Two threads writing a record without file locking | 188 |
| Program 5.7 | | Two threads writing a record with file locking | 190 |
| Program 5.8 | | Copy standard input to standard output using fgetc and fputc | 195 |
| Program 5.9 | | Copy standard input to standard output using fgets and fputs | 196 |
| Program 6.1 | | Determining a leap year | 202 |
| Program 6.2 | | Displaying information about the local time zone | 208 |
| Program 6.3 | | Printing login session length using gmtime | 211 |
| Program 6.4 | | Using mktime to determine what day of the week a given date is | 212 |
| Program 6.5 | | Using strftime to convert the time to various formats | 218 |
| Program 7.1 | | Using getlogin | 225 |
| Program 7.2 | | Using cuserid | 227 |
| Program 7.3 | | Getting and setting real and effective user IDs | 229 |
| Program 7.4 | | Getting and setting the current group set | 236 |
| Program 7.5 | | Searching by user name | 239 |
| Program 7.6 | | List all the users | 241 |
| Program 7.7 | | Searching the shadow password file by user name | 246 |
| Program 7.8 | | Listing all the passwords | 248 |
| Program 7.9 | | Traditional style password encryption | 252 |
| Program 7.10 | | New style password encryption | 254 |
| Program 7.11 | | Comparing passwords | 255 |
| Program 7.12 | | Searching by group name | 258 |
| Program 7.13 | | List all the groups | 260 |
| Program 7.14 | | Listing the logged-in users | 265 |
| Program 7.15 | | Printing users' last login times | 271 |
| Program 7.16 | | Listing the legal shells | 272 |
| Program 8.1 | | System information provided uname and sysinfo | 281 |
| Program 8.2 | | Displaying CPU and memory information | 292 |
| Program 8.3 | | Displaying some run time file limits | 295 |
| Program 8.4 | | Listing the supported user page sizes | 297 |
| Program 8.5 | | Print the current soft and hard resource limits | 301 |
| Program 8.6 | | Our implementation of the print_rctls function | 312 |
| Program 8.7 | | Our implementation of the print_rctl function | 313 |
| Program 8.8 | | Printing all the resource controls | 315 |
| Program 8.9 | | Modifying a resource control | 317 |
| Program 8.10 | | Time how long each command line argument takes to run | 321 |
| Program 8.11 | | Our implementation of getprusage | 329 |
| Program 8.12 | | Implementing getprusage using ioctl | 332 |
| Program 8.13 | | Displaying the system's load averages | 335 |
| Program 9.1 | | Using privilege bracketing | 342 |
| Program 9.2 | | Breaking out of a chroot jail | 345 |
| Program 10.1 | | Splitting a path into its component parts | 359 |
| Program 10.2 | | Print out the file type for each command line argument | 359 |
| Program 10.3 | | Demonstrating the access function | 366 |
| Program 10.4 | | Using the umask function | 368 |
| Program 10.5 | | Using the chmod function | 370 |
| Program 10.6 | | Unlinking a file | 379 |
| Program 10.7 | | Recursively list all the files in a directory | 384 |
| Program 10.8 | | Resolving symbolic links using realpath and resolvepath | 386 |
| Program 10.9 | | Display a file's access, modification, and inode modification times | 390 |
| Program 10.10 | | Changing a file's access and modification times | 392 |
| Program 10.11 | | Count the number of each type of file | 397 |
| Program 10.12 | | Recursively count the number of each type of file | 402 |
| Program 10.13 | | Change the current working directory | 404 |
| Program 10.14 | | Print the current working directory | 405 |
| Program 10.15 | | Print the st_dev and st_rdev fields of a file | 409 |
| Program 10.16 | | Print the entire contents of the stat structure | 412 |
| Program 11.1 | | Displaying information about mounted file systems | 422 |
| Program 11.2 | | Listing file systems mounted with a given option | 424 |
| Program 11.3 | | Setting a tag on a mounted file system | 427 |
| Program 11.4 | | Displaying information from /etc/vfstab | 430 |
| Program 11.5 | | Mounting a UFS file system | 436 |
| Program 11.6 | | Unmounting a file system | 438 |
| Program 11.7 | | Printing file system statistics | 441 |
| Program 11.8 | | Obtaining file system information using ustat | 443 |
| Program 11.9 | | Print the disk and inode use for each user | 455 |
| Program 12.1 | | Changing the INTR and KILL special input characters | 480 |
| Program 12.2 | | Using tcgetattr and tcsetattr to change the character size | 476 |
| Program 12.3 | | Changing the input baud rate | 486 |
| Program 12.4 | | Our implementation of isatty | 489 |
| Program 12.5 | | Our implementation of ttyname_r | 491 |
| Program 12.6 | | A function to read a user's password | 495 |
| Program 12.7 | | Set terminal to cbreak or raw mode | 499 |
| Program 12.8 | | Testing our raw and cbreak modes | 501 |
| Program 12.9 | | Print window size changes | 504 |
| Program 13.1 | | Using nonblocking I/O | 510 |
| Program 13.2 | | Our function to acquire or release a lock | 515 |
| Program 13.3 | | Our function to test for a lock | 516 |
| Program 13.4 | | Deadlock detection when file locking | 520 |
| Program 13.5 | | Copying a file that has a read lock on it | 523 |
| Program 13.6 | | Using isastream | 526 |
| Program 13.7 | | Copy a file using getmsg and write | 532 |
| Program 13.8 | | Listing the modules on a STREAMS device using ioctl | 535 |
| Program 13.9 | | Using fd_sets | 541 |
| Program 13.10 | | Using poll and nonblocking I/O to copy a file | 546 |
| Program 13.11 | | Using /dev/poll and nonblocking I/O to copy a file | 548 |
| Program 13.12 | | Using writev to write multiple buffers | 555 |
| Program 13.13 | | Copying a file using sendfile | 557 |
| Program 13.14 | | Writing a buffer using sendfile | 559 |
| Program 13.15 | | Copying a file and two buffers using sendfilev | 561 |
| Program 13.16 | | Copy a file using mmap and memcpy | 566 |
| Program 13.17 | | Sharing memory between related processes using /dev/zero | 569 |
| Program 13.18 | | Locking a file in memory | 576 |
| Program 13.19 | | Printing a file's ACL | 585 |
| Program 13.20 | | Setting a file's ACL | 587 |
| Program 13.21 | | Listing a file's extended attributes | 593 |
| Program 13.22 | | Changing permissions on an extended attribute file | 598 |
| Program 14.1 | | Example of how to use exit handlers | 608 |
| Program 14.2 | | Echo command line arguments to standard output | 609 |
| Program 14.3 | | Determining our executable's pathname | 610 |
| Program 14.4 | | Getting and setting environment variables | 613 |
| Program 14.5 | | The ubiquitous "hello world" program | 617 |
| Program 14.6 | | A program using nested functions | 620 |
| Program 14.7 | | Our example changed to use setjmp and longjmp | 622 |
| Program 14.8 | | The effect of longjmp on automatic, register, and volatile variables | 624 |
| Program 14.9 | | Incorrect usage of an automatic variable | 626 |
| Program 15.1 | | An example of the fork function | 634 |
| Program 15.2 | | An example of the vfork function | 638 |
| Program 15.3 | | Describe the termination status of a process | 642 |
| Program 15.4 | | Demonstrating different termination statuses | 643 |
| Program 15.5 | | Avoiding zombies by calling fork twice | 645 |
| Program 15.6 | | Program with a race condition | 650 |
| Program 15.7 | | Reimplementation of Program 15.6 avoiding race condition | 651 |
| Program 15.8 | | Demonstrating the exec functions | 658 |
| Program 15.9 | | Echo all the command line arguments and environment variables | 659 |
| Program 15.10 | | A program that execs an interpreter file | 663 |
| Program 15.11 | | An awk script as an interpreter file | 664 |
| Program 15.12 | | Our implementation of the system function (without signal handling) | 668 |
| Program 15.13 | | Testing our implementation of the system function | 669 |
| Program 15.14 | | Program to generate some process accounting entries | 673 |
| Program 15.15 | | Print selected fields from process accounting file | 675 |
| Program 16.1 | | Creating an orphaned process group | 698 |
| Program 17.1 | | Catching the signals SIGUSR1 and SIGUSR2 by using signal | 715 |
| Program 17.2 | | Catching the signals SIGUSR1 and SIGUSR2 by using sigset | 721 |
| Program 17.3 | | Calling non-reentrant functions from a signal handler | 727 |
| Program 17.4 | | A SIGCLD signal handler that can be problematic | 730 |
| Program 17.5 | | Our first attempt at implementing sleep | 736 |
| Program 17.6 | | Avoiding the race condition in our first version of sleep | 737 |
| Program 17.7 | | Calling ssp_sleep from a program that catches other signals | 738 |
| Program 17.8 | | Collecting user input with a timeout | 739 |
| Program 17.9 | | Collecting user input with a timeout, helped by setjmp and longjmp | 741 |
| Program 17.10 | | Collecting user input with an interval timer timeout | 745 |
| Program 17.11 | | Printing the current signal mask | 749 |
| Program 17.12 | | Example of signal sets, sigprocmask, and sigpending | 750 |
| Program 17.13 | | Our implementation of signal using sigaction | 759 |
| Program 17.14 | | Printing signal information in a signal handler | 760 |
| Program 17.15 | | Trapping invalid operation floating-point exceptions | 763 |
| Program 17.16 | | How sigsetjmp and siglongjmp interact with signal masks | 765 |
| Program 17.17 | | Protecting a critical region of code from a signal | 770 |
| Program 17.18 | | Waiting for a global variable to be set | 772 |
| Program 17.19 | | Functions that enable a child and parent to synchronize using signals | 775 |
| Program 17.20 | | Our implementation of the abort function | 777 |
| Program 17.21 | | Using ssp_system to invoke ex | 778 |
| Program 17.22 | | An implementation of system that handles signals correctly | 780 |
| Program 17.23 | | Execute the command line argument using system | 783 |
| Program 17.24 | | Our final implementation of sleep | 786 |
| Program 17.25 | | Handling SIGTSTP | 789 |
| Program 17.26 | | Using software signals | 791 |
| Program 17.27 | | Using an alternate stack for a signal handler | 794 |
| Program 17.28 | | Printing signal information using psignal and psiginfo | 799 |
| Program 17.29 | | Our implementation of the kill command | 801 |
| Program 18.1 | | Generating a log message | 810 |
| Program 18.2 | | Using the syslog facility | 816 |
| Program 18.3 | | Our daemon_init function | 818 |
| Program 18.4 | | Testing our daemon_init function | 821 |
| Program 18.5 | | Our one_copy function | 823 |
| Program 18.6 | | Testing our one_copy function | 824 |
| Program 19.1 | | Sending data from parent to child over a pipe | 833 |
| Program 19.2 | | Sending email through a pipe | 835 |
| Program 19.3 | | Functions that enable a child and parent to synchronize using pipes | 838 |
| Program 19.4 | | Sending email through a pipe using popen | 841 |
| Program 19.5 | | Our implementation of popen | 842 |
| Program 19.6 | | Our implementation of pclose | 844 |
| Program 19.7 | | Support functions for popen and pclose | 846 |
| Program 19.8 | | Our modified version of rot13 | 848 |
| Program 19.9 | | Invoking rot13 using our version of popen and pclose | 849 |
| Program 19.10 | | A simple coprocess to calculate the square root of a number | 850 |
| Program 19.11 | | Program to drive the sqrt coprocess | 851 |
| Program 19.12 | | Another version of sqrt, using standard I/O | 853 |
| Program 19.13 | | FIFO server that can handle multiple clients | 859 |
| Program 19.14 | | FIFO client that works with the server in Program 19.13 | 862 |
| Program 20.1 | | Obtain a System V IPC key based on a pathname | 870 |
| Program 20.2 | | Create a System V message queue | 879 |
| Program 20.3 | | Add a message to a System V message queue | 880 |
| Program 20.4 | | Remove a message from a System V message queue | 882 |
| Program 20.5 | | Remove a System V message queue | 883 |
| Program 20.6 | | List all messages currently in System V message queues | 887 |
| Program 20.7 | | Create a System V semaphore set | 897 |
| Program 20.8 | | Remove a System V semaphore set | 898 |
| Program 20.9 | | Set the values of semaphores in a semaphore set | 899 |
| Program 20.10 | | Get the values of semaphores in a semaphore set | 900 |
| Program 20.11 | | Perform operations on a System V semaphore set | 902 |
| Program 20.12 | | List all the System V semaphore sets | 905 |
| Program 20.13 | | Create a System V shared memory segment | 913 |
| Program 20.14 | | Write to a System V shared memory segment | 914 |
| Program 20.15 | | Read from a System V shared memory segment | 915 |
| Program 20.16 | | Remove a System V shared memory segment | 916 |
| Program 20.17 | | List all the System V shared memory segments | 918 |
| Program 20.18 | | Copy 100 MB using a System V message queue | 921 |
| Program 20.19 | | Copy 100 MB using a pipe | 922 |
| Program 20.20 | | Access a shared resource using a lock file | 923 |
| Program 20.21 | | Access a shared resource using a System V semaphore | 925 |
| Program 21.1 | | The send_fd and send_err functions | 930 |
| Program 21.2 | | The recv_fd function | 931 |
| Program 21.3 | | The client's main function | 933 |
| Program 21.4 | | The cs_open function | 934 |
| Program 21.5 | | The first server's main function | 935 |
| Program 21.6 | | The do_request function | 936 |
| Program 21.7 | | The buf2args and parse_args functions | 937 |
| Program 21.8 | | The srv_listen function | 941 |
| Program 21.9 | | The srv_accept function | 943 |
| Program 21.10 | | The cli_connect function | 943 |
| Program 21.11 | | The cs_open function | 944 |
| Program 21.12 | | Preamble for version 2 of our open server | 945 |
| Program 21.13 | | The second server's main function | 946 |
| Program 21.14 | | The loop function | 947 |
| Program 21.15 | | The add_entry and del_entry functions | 949 |
| Program 22.1 | | A simple door client | 958 |
| Program 22.2 | | A simple door server | 959 |
| Program 22.3 | | Door client modified to print address and size of result | 961 |
| Program 22.4 | | Door server that handles an unreferenced invocation | 963 |
| Program 22.5 | | The main function of our multiple unreferenced invocations server | 966 |
| Program 22.6 | | The server procedure of our multiple unreferenced invocations server | 967 |
| Program 22.7 | | Server procedure that prints the client's credentials | 969 |
| Program 22.8 | | Print information about a door | 972 |
| Program 22.9 | | Door client for descriptor passing example | 975 |
| Program 22.10 | | Door server procedure for descriptor passing example | 976 |
| Program 22.11 | | The main function of our server that manages its own threads | 980 |
| Program 22.12 | | The server creation function of our server that manages its own threads | 981 |
| Program 22.13 | | The thread start function of our server that manages its own threads | 983 |
| Program 22.14 | | The server procedure of our server that manages its own threads | 984 |
| Program 22.15 | | A server procedure that terminates itself | 986 |
| Program 22.16 | | Server procedure for idempotent server example | 987 |
| Program 22.17 | | Client that calls door_call again when SIGCHLD is received | 988 |
| Program 22.18 | | A client that terminates during a door_call | 990 |
| Program 22.19 | | A server procedure that detects premature client termination | 991 |
| Program 23.1 | | Function to open a pseudo terminal master device | 1007 |
| Program 23.2 | | Function to open a pseudo terminal slave device | 1008 |
| Program 23.3 | | Our pty_fork function | 1010 |
| Program 23.4 | | Our pty program's main function | 1012 |
| Program 23.5 | | The pty program's loop function | 1015 |
| Program 23.6 | | Implementing the script program using pty | 1019 |
| Program 23.7 | | The run_driver function for the pty program | 1024 |
| Program 23.8 | | Script to drive the passwd program | 1025 |
| Program 23.9 | | The pckt program's loop function | 1027 |
| Program 23.10 | | Program to test packet mode pseudo terminals | 1031 |
| Program A.1 | | An internationalized version of our greeting program | 1043 |
| Program D.1 | | Our header file, ssp.h | 1117 |
| Program D.2 | | Our standard error functions | 1119 |
| Program D.3 | | Our file status flag functions | 1121 |
| Program D.4 | | Our function to acquire or release a lock on a file section | 1122 |
| Program D.5 | | Our readn and writen functions | 1123 |
| Program D.6 | | Our function to print the termination status of a process | 1124 |
| Program D.7 | | Our version of snprintf | 1124 |
| Program E.1 | | Determine a file's size by using lseek | 1128 |
| Program E.2 | | Our function to convert an arbitrarily based number to a string | 1129 |
| Program E.3 | | Get a lastlog entry for a given user ID | 1132 |
| Program E.4 | | Writing to a file that is underneath a mount point | 1137 |
| Program E.5 | | Accessing a file after its file system has been unmounted | 1138 |
| Program E.6 | | Measuring the capacity of a pipe by using poll | 1140 |
| Program E.7 | | Incorrect use of vfork | 1142 |
| Program E.8 | | Create a zombie and look at it using ps | 1143 |
| Program E.9 | | Print a terminal's foreground process group ID | 1144 |
| Program E.10 | | Create a new session | 1145 |
| Program E.11 | | Print the number of the highest open file descriptor | 1147 |
| Program E.12 | | Portably opening a FIFO for reading and writing | 1149 |
| Program E.13 | | Passing a door descriptor in a cookie to avoid making it global | 1151 |
| Program E.14 | | Adding start and stop timestamps to our version of script | 1180 |
| Figure 1.1 | | Summary of the different file system types | 8 |
| Figure 1.2 | | System call latency on four architectures | 30 |
| Figure 1.3 | | Relationship of applications, library functions, and system calls | 30 |
| Figure 1.4 | | C data type sizes in bits for the ILP32 and LP64 data type models | 33 |
| Figure 1.5 | | The effect of the various compilation environments | 42 |
| Figure 2.1 | | Standards compliance of Solaris | 54 |
| Figure 2.2 | | Commands and flags required to build standards conforming applications | 55 |
| Figure 3.1 | | Alignment of various word sizes | 95 |
| Figure 3.2 | | Memory layout of our structure | 95 |
| Figure 3.3 | | Memory layout of our reordered structure | 96 |
| Figure 3.4 | | Red zones | 105 |
| Figure 3.5 | | Results from running Program 3.14 | 106 |
| Figure 4.1 | | Availability of open flags | 127 |
| Figure 4.2 | | The effect of buffer size on file I/O | 135 |
| Figure 4.3 | | Kernel structures used for open files | 137 |
| Figure 4.4 | | Kernel structures for two processes opening the same file | 138 |
| Figure 4.5 | | Kernel structures after dup | 142 |
| Figure 4.6 | | Categories of fcntl cmd arguments | 143 |
| Figure 4.7 | | File access flags | 144 |
| Figure 4.8 | | Availability of fcntl cmds | 147 |
| Figure 4.9 | | The effect of O_DSYNC and O_SYNC on file copy times | 152 |
| Figure 4.10 | | Summary of how direct I/O affects sequential file I/O | 156 |
| Figure 5.1 | | The effect of the values of mode on fopen, freopen, and fdopen | 161 |
| Figure 5.2 | | Conversion characters | 177 |
| Figure 5.3 | | Precision modifiers | 179 |
| Figure 5.4 | | Conversion specification flag characters | 181 |
| Figure 5.5 | | Size modifiers | 182 |
| Figure 5.6 | | The effect of buffer size on standard (character) I/O | 197 |
| Figure 5.7 | | The effect of buffer size on standard (line and unlocked) I/O | 197 |
| Figure 5.8 | | Summary results from Programs 5.8 and 5.9 | 198 |
| Figure 5.9 | | I/O buffer sizes for different values of buf_size | 198 |
| Figure 6.1 | | The relationship of the various time functions | 209 |
| Figure 7.1 | | Relationship between the functions that modify the different user IDs | 233 |
| Figure 7.2 | | The different ways to change the three user IDs | 234 |
| Figure 8.1 | | Availability of sysinfo commands | 280 |
| Figure 8.2 | | Variables that return -1 without setting errno | 291 |
| Figure 8.3 | | The effect of limits on implementation-defined constants | 300 |
| Figure 8.4 | | Resource controls available in Solaris 9 | 303 |
| Figure 10.1 | | The effect of dirname and basename on different paths | 355 |
| Figure 10.2 | | File type macros | 358 |
| Figure 10.3 | | Masks to determine file access permissions | 364 |
| Figure 10.4 | | Other file access permission masks | 364 |
| Figure 10.5 | | Masks to determine file access permissions | 369 |
| Figure 10.6 | | Logical layout of file systems, cylinder groups, and inode lists | 374 |
| Figure 10.7 | | File system in more detail | 376 |
| Figure 10.8 | | File system detail after creating a test directory | 378 |
| Figure 10.9 | | How symbolic links are handled by various functions | 382 |
| Figure 10.10 | | The effect of functions on a file's access, update, and inode update times | 389 |
| Figure 11.1 | | Standard file system types | 433 |
| Figure 11.2 | | The standard mount options | 434 |
| Figure 11.3 | | Values of fs_clean | 449 |
| Figure 11.4 | | Constants that help with superblock I/O | 449 |
| Figure 11.5 | | UFS inode direct and indirect blocks | 453 |
| Figure 11.6 | | Macros for handling inode numbers | 453 |
| Figure 12.1 | | Terminal device input and output queues | 463 |
| Figure 12.2 | | Terminal line discipline | 464 |
| Figure 12.3 | | Terminal flag summary | 466 |
| Figure 12.4 | | Summary of terminal I/O functions | 468 |
| Figure 12.5 | | Relationship between the terminal device functions | 468 |
| Figure 12.6 | | Summary of special input characters | 469 |
| Figure 12.7 | | Availability of special input characters | 470 |
| Figure 12.8 | | The four cases for non-canonical input | 497 |
| Figure 13.1 | | The effect of O_NONBLOCK and O_NDELAY on a blocking read | 508 |
| Figure 13.2 | | The effect of O_NONBLOCK and O_NDELAY on a blocking write | 509 |
| Figure 13.3 | | The interoperability of different lock types | 512 |
| Figure 13.4 | | The effect of mandatory locking on I/O by other processes | 521 |
| Figure 13.5 | | Effect of mandatory locking on file I/O performance | 522 |
| Figure 13.6 | | Anatomy of a simple stream | 525 |
| Figure 13.7 | | STREAMS message type created by write, putmsg, and putpmsg | 529 |
| Figure 13.8 | | STREAMS message type retrieved by read, getmsg, and getpmsg | 530 |
| Figure 13.9 | | Overview of the talk program | 537 |
| Figure 13.10 | | The talk program using two processes | 538 |
| Figure 13.11 | | Visualization of the fd_set data type | 540 |
| Figure 13.12 | | The effect of poll and /dev/poll on nonblocking I/O efficiency | 549 |
| Figure 13.13 | | Details of the array of iovec structures used by readv and writev | 554 |
| Figure 13.14 | | Timing results for different methods of writing two buffers | 555 |
| Figure 13.15 | | Memory mapped file | 563 |
| Figure 13.16 | | Comparing the time to copy a file using Programs 4.2 and 13.16 | 567 |
| Figure 14.1 | | Relationship of a C program's start-up and termination functions | 607 |
| Figure 14.2 | | An example environment variable list | 611 |
| Figure 14.3 | | Address space for 32-bit SPARC sun4u processes | 615 |
| Figure 14.4 | | Stack frames after do_foo has been called | 621 |
| Figure 15.1 | | Sharing of open files between parent and child | 636 |
| Figure 15.2 | | Summary of the six exec functions | 661 |
| Figure 15.3 | | Relationship of the six exec functions | 661 |
| Figure 15.4 | | Values for ac_flag in a process accounting record | 671 |
| Figure 15.5 | | Process hierarchy for Program 15.14 | 674 |
| Figure 16.1 | | Arrangement of processes to allow terminal logins | 678 |
| Figure 16.2 | | Arrangement of processes once we've logged in from a terminal | 679 |
| Figure 16.3 | | Sequence of processes when running the TELNET server | 681 |
| Figure 16.4 | | Arrangement of processes once we've logged in from the network | 681 |
| Figure 16.5 | | Arrangement of a process and its offspring | 682 |
| Figure 16.6 | | Arrangement of processes in a process group | 683 |
| Figure 16.7 | | A session consisting of three process groups | 685 |
| Figure 16.8 | | A session with three process groups showing the controlling terminal | 687 |
| Figure 16.9 | | Summary of job control features | 692 |
| Figure 16.10 | | Processes in a pipeline when invoked by /bin/sh | 695 |
| Figure 16.11 | | Processes in a pipeline when invoked by /bin/ksh | 697 |
| Figure 16.12 | | Arrangement of processes from Program 16.1 | 700 |
| Figure 17.1 | | Solaris signal summary | 706 |
| Figure 17.2 | | Features provided by the different signal handling functions | 724 |
| Figure 17.3 | | Reentrant functions that can be called from a signal handler | 726 |
| Figure 17.4 | | Similarities between the SVR4 and POSIX signal mechanisms | 746 |
| Figure 17.5 | | Values of si_code for system-generated signals | 758 |
| Figure 17.6 | | Time line for Program 17.16 | 767 |
| Figure 17.7 | | Process groups for Program 17.21 | 779 |
| Figure 18.1 | | Details of the STREAMS log facility | 808 |
| Figure 18.2 | | Details of the syslog facility | 812 |
| Figure 19.1 | | Conceptual representation of a pipe | 830 |
| Figure 19.2 | | Arrangement of SVR4 STREAMS pipes | 831 |
| Figure 19.3 | | Arrangement of a pipe after fork | 831 |
| Figure 19.4 | | Arrangement of a pipe between parent and child | 832 |
| Figure 19.5 | | Arrangement of pipes for synchronizing parent and child processes | 837 |
| Figure 19.6 | | Result of fp = popen (command, "r") | 839 |
| Figure 19.7 | | Result of fp = popen (command, "w") | 840 |
| Figure 19.8 | | Driving a coprocess by using two one-way pipes | 848 |
| Figure 19.9 | | Driving a coprocess by using a full-duplex pipe | 849 |
| Figure 19.10 | | Procedure that processes filtered data twice | 855 |
| Figure 19.11 | | Process arrangement when using a FIFO to connect two pipelines | 856 |
| Figure 19.12 | | Clients sending requests to a server via a well-known FIFO | 857 |
| Figure 19.13 | | Client-server communications using FIFOs | 857 |
| Figure 20.1 | | The effect of flags when creating or opening an IPC object | 871 |
| Figure 20.2 | | Summary of IPC permissions | 872 |
| Figure 20.3 | | System V message queue tunables | 874 |
| Figure 20.4 | | Message type retrieved by msgrcv for different values of msgtyp | 877 |
| Figure 20.5 | | System V semaphore tunables | 892 |
| Figure 20.6 | | System V shared memory tunables | 909 |
| Figure 20.7 | | Performance comparison of message queues and pipes | 920 |
| Figure 20.8 | | Performance comparison of semaphores and record locking | 924 |
| Figure 21.1 | | Passing a file descriptor from one process to another | 928 |
| Figure 21.2 | | Pipe after pushing the connld module onto one end | 942 |
| Figure 21.3 | | Client-server connections on a named pipe | 942 |
| Figure 22.1 | | The three types of function call scenarios | 952 |
| Figure 23.1 | | Arrangement of pseudo terminals | 998 |
| Figure 23.2 | | Arrangement of processes when using dtterm | 999 |
| Figure 23.3 | | Arrangement of processes when using sshd to provide network logins | 1000 |
| Figure 23.4 | | Arrangement of processes when running the script program | 1001 |
| Figure 23.5 | | Driving a coprocess via a pseudo terminal | 1002 |
| Figure 23.6 | | Monitoring the output of a long-running program using a pseudo terminal | 1003 |
| Figure 23.7 | | Arrangement of processes when running cat from our pty program | 1017 |
| Figure 23.8 | | Arrangement of processes when using our ssp_script shell script | 1020 |
| Figure 23.9 | | Running a coprocess with a pseudo terminal as its input and output | 1021 |
| Figure 23.10 | | Arrangement of processes when using a driver program with pty | 1023 |
| Figure A.1 | | Precedence of environment variables for setting locales | 1038 |
| Figure B.1 | | Obsolescent SCP-originated functions | 1053 |
| Figure B.2 | | SCP-originated functions that are not obsolescent | 1054 |
| Figure C.1 | | Function availability (from _exit to ascftime) | 1104 |
| Figure C.2 | | Function availability (from asctime to door_create) | 1105 |
| Figure C.3 | | Function availability (from door_cred to fgets) | 1106 |
| Figure C.4 | | Function availability (from fgetspent to getgrgid) | 1107 |
| Figure C.5 | | Function availability (from getgrgid_r to getutxent) | 1108 |
| Figure C.6 | | Function availability (from getutxid to malloc) | 1109 |
| Figure C.7 | | Function availability (from mallopt to psignal) | 1110 |
| Figure C.8 | | Function availability (from ptsname to rmdir) | 1111 |
| Figure C.9 | | Function availability (from sbrk to sigdelset) | 1112 |
| Figure C.10 | | Function availability (from sigemptyset to strncat) | 1113 |
| Figure C.11 | | Function availability (from strncmp to ttyname_r) | 1114 |
| Figure C.12 | | Function availability (from tzset to writev) | 1115 |
| Figure D.1 | | Summary of our standard error functions | 1119 |
| Figure E.1 | | Summary of running different versions of Program 1.10 | 1128 |
| Figure E.2 | | Minimum set of files required in a chroot jail | 1134 |
| Figure E.3 | | Stack frame for Program E.7 | 1141 |
| Figure E.4 | | Stack frames while Program 17.7 is executing | 1145 |