Practical UNIX Programming:
A Guide to Concurrency, Communication, and Multithreading

by Kay A. Robbins and Steven Robbins
Prentice Hall, 1996


Errata

Recent Additions not corrected in the second printing:

page 5, Table 1.1, the entry for Context Switch should be 100,000 ns (100 us) (found by R. Fellinger)
page 9, first sentence of Section 1.1.2, "a event" should be "an event" (found by G. Longstreet)
page 22, Program 1.2, in the comments, arvp should be argvp (found by D. Gawlik)
page 36, Program 2.2, second line on page, remove parens around newnode + sizeof(list_t), (found by G. Riley)
page 48, middle of page, WEXITSTUS should be WEXITSTATUS (found by D. Gawlik)
page 51, Example 2.10, change 3 lines to:

   pid_t childpid, waitreturn;
   while (childpid != (waitreturn = wait(&status)))
      if ((waitreturn == -1) && (errno != EINTR)) 
page 51, Example 2.11, should start out "The following code segment waits for all available children,"
page 54, in the synopsis for execle, arg0[] should be arg0 (found by Z. Liu)
page 56, Program 2.7, last while has same problem as on page 51, Example 2.10
page 57, Program 2.8, last while has same problem as on page 51, Example 2.10
page 71, last line of first paragraph, the word "system" appears twice. (found by S. Laskowski)
page 75, in the add_data prototype, "*char monitorname" should be "char *monitorname"
page 80, remove the "extern" from the synopsis for getcwd (found by I. Mason)
page 80, first sentence after the SYNOPSIS, "accomodate." should be replaced by "accomodate, including the trailing string terminator."
page 80, second sentence after the SYNOPSIS, "returns -1" should be "returns NULL" (found by J. Morrison)
page 80, Example 3.2, the call to getcwd should be getcwd(mycwd, PATH_MAX + 1)
page 80, 3rd line from the bottom, MAX_PATH should be PATH_MAX (found by K. Barthelmann)
page 81, Example 3.3, the call to getcwd should be getcwd(mycwd, maxpath + 1)
page 81, Example 3.3, the second perror should be replaced with an fprintf as follows:
fprintf(stderr, "Could not allocate space for pathname\n");
(found by K. Barthelmann)
page 93, Figure 3.6, the first sentance in the caption should read "The situation after editing a file."
page 94, In Example 3.8 the ln command has the arguments in the wrong order, it should be: ln -s /dirA/name1 /dirB/name2 (found by G. Jenkins)
page 99, first line after Table 3.1, myfd should be fd (found by T. Zhou) or better, reference to fd in Example 3.10 on page 98 should be myfd (suggested by P. Chen)
page 110, Example 3.20, change the word "redirection" to "pipe" (found by G. Page)
page 113, The title of Section 3.6 should be Reading from and Writing To Files (found by Z. Liu)
page 117, last line on the page, readfd should be readfds (found by R. Fellinger)
page 121, Exercise 3.12. Neither POSIX.1 or SPEC 1170 specifies what will happen if one process opens a FIFO with O_RDONLY and another opens with O_WRONLY when O_NONBLOCK is clear. Many operating systems handle this in the desired way, that is they do not deadlock. (found by M. Albert)
page 129, first paragraph after the directory list, "Breath-first" should be "Breadth-first" and the name of the function should be similarly changed (found by D. Gawlik)
page 131, in the paragraph before Example 3.32, pr_status_t should be prstatus_t (found by Z. Liu)
page 132, Figure 3.21, a group of 7 lines appears twice
page 143, end of first line of last paragraph, "the first pipe to the" should be "the first pipe from the" (found by B. Wu)
page 154, middle of page after Phase k, double between (found by J. Choo)
pages 161 and 162, The example would have been clearer if the rows of the original matrix had been stored in the rows of a rather than in the columns of a.
page 173, last line before Example 5.6, "is is often" should be "is often" (found by B. Wu)
page 180, last sentence before Example 5.14, SIG_IGN values should be SIG_IGN value (found by B. Wu)
page 186, Program 5.1, get_file_size should return a long instead of an int (found by R. Fellinger)
page 195, replace the end of the next to last sentence before Program 5.3, beginning with the phrase "blocks the signal" with "and suspends itself until a signal comes in."
page 196, Program 5.4, remove the 4 lines that refer to sigset
page 208, last sentence, "which has a least" should be "which has at least" (found by J. Buch)
page 212, Program 6.1 needs an include of unistd.h
page 212, Program 6.1, main should be void main(void)
page 220, 6th line of 3rd paragraph, "on the each clock tick" should be "on each clock tick" (found by J. Buch)
page 239, Program 6.6, the include of hardware.h should be hardware_timer.h
page 242, last line of 1st paragraph of Section 6.9, "and program can" should be "and the program can" (found by J. Buch)
page 250, 2nd line of text, "handler, When" should be "handler. When" (found by J. Buch)
pages 307-8, Program 8.2 is incorrect. Unnamed semaphores cannot sychronize between processes unless they are in shared memory. A correct version of Program 8.2 using named semaphores can be downloaded from the Chapter 8 section of the programs page.
page 312, 7th line from the bottom, ICP_CREAT should be IPC_CREAT (found by C. Thorne)
page 316, Example 8.23, under Process 3, "use tape A" should be "use tape B" (found by J. Watts)
page 320, Program 8.5, second line from the bottom should be "return semid;" (found by R. Male)
page 335, last paragraph before Section 9.1.1, "Example 5.5" should be "Program 5.5" (found by R. Hatch)
page 340, Program 9.4, insert the line "#define BUFSIZE 1024" after the includes.
page 342, Program 9.5, insert the line "#define BUFSIZE 1024" after the includes.
page 344, Program 9.6, insert the line "#define BUFSIZE 1024" after the includes.
pages 346-370, POSIX thread functions return 0 on success and an error number on failure. They do not set errno. See the corrections here.
pages 347 and 348, The last sentence of page 347 beginning "If a property of ... " should be replaced by "The attribute object only affects a thread at the time of thread creation."
page 353, The last sentence in the second paragraph should be replaced with: "Detached threads free their resources on exit. A thread can become detached by calling pthread_detach. (found by T. Stiemerling)
page 360, replace the sentence beginning "When a property ..." with "However, the attribute object only affects a thread at the time of thread creation." (found by T. Stiemerling)
page 362, The statement at the beginning of Example 9.6 should read "The following code segment creates a do_it thread with the default attributes, except that the priority is HIGHPRIORITY." The code segment is also incorrect. The correct code can be found in the program files for Chapter 9.
page 362, The last paragraph should be rewritten to reflect the change to Example 9.6
page 363, second paragraph in second bulleted item, "does does" should be "does" (found by K. Barthelmann)
page 367, Example 10.1, in the if statement, remove the ! before pthread_mutex_init. (found by L. Das)
page 367, first line after the synopsis, "function" should be "functions" (found by K. Barthelmann)
pages 389-390, In Program 10.7 consumer code, "cond_wait" and "cond_signal" should be "pthread_cond_wait" and "pthread_cond_signal".
page 393, In Program 10.8, the call to sigwait should be sigwait(&intmask,&sig) and sig should be declared as an int. (found by B. Pich)
page 394, In Program 10.8 consumer code, "cond_wait" and "cond_signal" should be "pthread_cond_wait" and "pthread_cond_signal".
page 372, Example 10.4, producer for loop is missing braces
page 433, line 9 after figure, forgable should be forgeable (found by J. Choo)
page 440, Program 12.2, near the end, close(communfd) should be u_close(communfd) (found by R. Burns)
page 441, Program 12.2, "int child" should be "pid_t child" (reported by I. Mason)
page 442, Program 12.3, near the end, close(communfd) should be u_close(communfd)
page 449, third paragraph from the bottom, "The combination of open ..." should be "The combination of socket ..." (found by R. Hatch)
page 452, synopsis for connect, second parameter should be const struct sockaddr *address (found by K. Barthelmann)
page 483, near bottom of page, insert semicolon after buffer_t (reported by I. Mason)
page 484, second line from the bottom of the first bullet, "must be less than" should be "must not exceed" (reported by I. Mason)
page 490, first three lines of Section 13.10, "inforadio.com" should be "info@radio.com" and "sitesradio.com" should be "sites@radio.com" (found by R. Hatch)
page 502, Figure 14.6, the box containing proto_xdr.c should not be shaded (found by K. Barthelmann)
page 503, Program 14.5, the indentation is missing (found by K. Barthelmann)
page 506, Program 14,7, the indentation is missing
page 587, paragraph after Example A.17, "can can" should be "can" (found by K. Hui)
page 591, second line from the bottom, "symbol definitions" should be "symbol declarations" (found by C. Smith)
page 606, Program B.4, in the comments for u_connect, "inetp" should be "hostn" (found by R. Hatch)
page 607, Program B.4, in the comments for u_read and u_write, "TLI file descriptor" shoud be "file descriptor" (found by J. Watts)
pages 607-608, Program B.4, in the comments of u_read and u_write, "nbyte" should be "size" (found by R. Hatch)
page 609, Program B.5, in the comments for u_open, "s" should be "port" (found by R. Hatch)
page 611, RPgoram B.5, in the comments for u_connect, "inept" should be "inetp" (found by R. Hatch)
page 617, Program B.8, in the comments for u_open, "s" should be "port" (found by R. Hatch(
page 619, Program B.8, in the comments for u_connect, "inept" should be "hostn" and in the comments for u_read "nbyte" should be "size" (found by R. Harch)
page 620, Program B.8, in the comments for u_write, "nbyte" should be "size" (found by R. Hatch)
pages 621-630, in various places the data type unsigned short is used where u_port_t should be. (found by J. Watts)
page 639, reference 95, Timer Facility should be in lower case


The following errors have been corrected in the second printing.

page 27, 5th line from the bottom, "The standard is surprising readable" should be "The standard is surprisingly readable (found by N. Wagner)
page 30, second line, "operating system keeps tracks" should be operating system keeps track (found by R. Ganley)
page 76, 8th line from the bottom, "MINUX" should be "MINIX" (found by N. Wagner)
page 91, in Example 3.7, the ln command has the arguments in the wrong order, it should be: ln /dirA/name1 /dirB/name2 (found by C. Sharp)
pages 91-93. While many editors work as described in the answer to Exercise 3.4, vi typically does not. (found by C. Sharp)
page 124, 4th line from bottom of Program 3.4, "return byteswritten" should be "return (int)byteswritten" (found by R. Shenk)
page 185, 11th line from the bottom, "signal handler is enters." should be "signal handler is entered." (found by R. Shenk)
page 198, line 2. After I/O the comma should be a period. (found by R. Shenk)
page 236, blank entry in active list in Figure 6.7 should be -1
page 346, Program 9.7, last line of page, "void process_command(char *, int);" should be "void *process_fd(void *arg);" (found by J. Potocki)
page 347, line 5 in Program 9.7, a space is missing between tid and = (found by R Shenk)
page 351, line 3 in Program 9.8 should be "else if (bytes_written < 0)" (found by J. Peacock)
page 368, line 3, "do not not have" should be "do not have" (found by J. Potocki)
page 370, in main of Program 10.2, two occurrences of thread_t should be pthread_t (found by J. Potocki)
page 374, in main of Program 10.3, two occurrences of thread_t should be pthread_t (found by J. Potocki)
page 379, line 12, "the... thread blocks so than another thread ..." should be " thread blocks so that another thread ... " (found by R. Shenk)
page 384, Program 10.6, 4th line from bottom, "cond_wait" should be "pthread_cond_wait" (found by B. Danielson)
page 385, in main of Program 10.6, two occurrences of thread_t should be pthread_t (found by J. Potocki)
page 385, Program 10.6, 8th line, "cond_signal" should be "pthread_cond_signal"
page 387, line 6 from the bottom, "almost identical to the one is Program 10.6" should be "almost identical to the one in Program 10.6 (found by R. Shenk)
page 390, in main of Program 10.7, two occurrences of thread_t should be pthread_t (found by J. Potocki)
page 394, in main of Program 10.8, three occurrences of thread_t should be pthread_t (found by J. Potocki)
page 472, last line of Program 12.16, remove blank before }
page 473, Program 12.17, first line, # left out before include (found by J. Peacock)
page 578, middle of page, paragraph starting "Each man page ...", "similar to way that" should be "similar to the way that" (found by R. Shenk)
page 607, Program B.4, in u_read, "int retval" should be "ssize_t retval"
page 608, Program B.4, line 6, "int u_write" should be "ssize_t u_write" (found by R. Shenk)
page 608, Program B.4, line 8, "int retval" should be "ssize_t retval"
page 619, Program B.8, 2nd line from bottom, "int retval" should be "ssize_t retval"
page 620, Program B.8, middle of page, "int u_write" should be "ssize_t u_write" (found by R. Shenk)
page 620, Program B.8, middle of page, "int retval" should be "ssize_t retval"
page 630, 5th line, remove blank before }