Advanced Linux Programming
Author: CodeSourcery, LLC
Description: Advaned Linux Programming web site

### Reporting an Error

Should you find an error in Advanced Linux Programming that is not already listed here, please send mail to alp-errata@advancedlinuxprogramming.com.

### Errata for Advanced Linux Programming

- page iv (publication information)

  Due to an oversight in production, an incorrect copyright notice was included. The copyright notice should read:

  > Advanced Linux Programming
  > FIRST EDITION: June, 2001
  > Copyright © 2001 by New Riders Publishing. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, Version 1, no options exercised. (The latest version of this license is available at `http://www.opencontent.org/openpub/`).

- page xx

  The term "GNU/Linux" is misspelled as "GNU/Liux."

- page 6

  In Listing 1.1, add `#include <stdlib.h>` since `atoi` is used.

- page 8

  The first paragraph of Section 1.2.2 should refer to `reciprocal.cpp`, not `utilties.cpp`.

- page 31

  In the third paragraph, the third sentence should read:

  > You should still always check for invalid input and produce sensible error messages in response to such input.

  The words "to such" are missing in the book as printed.
- page 34

  In the code, the comment for `case ENOENT` should read `PATH does not exist`.

- page 38

  The first sentence in Section 2.3.2 should refer to an archive rather than a archive.

- page 38

  In the last sentence of the text, omitting the sidebar, the resulting object file is `test1.o`, not `test.o`.

- page 39

  In the first paragraph, the linker stops searching directories.

- page 41

  In the paragraph beginning with "Static libraries", modify "If decide to link" to "If you decide to link".

- page 41

  When linking statically, linking in the math library is also required. Thus, the compilation line becomes `gcc -static -o tifftest tifftest.c -ltiff -ljpeg -lz -lm`.

- page 43

  The indented line of code near the bottom of the page should refer to `my_function`, not `foo`.

- page 48

  In the first paragraph, the first technique has "considerable risks", not "considerably risks".

- page 53

  The word "it" in the last sentence of the second paragraph should instead be "is". In particular, the sentence should read:

  > The default disposition for these signals is to terminate the process and produce a core file.

- page 57

  The word "is" in the last sentence should instead be "it." In particular, the sentence should read:

  > Instead, when a child process terminates, it becomes a zombie process.

- page 60

  The code in `clean_up_child_process` would not work correctly if there were more than one child process. The Linux kernel will only call the signal handler once if two or more child processes terminate at almost the same time. Therefore, if there is may be more than one child process, the signal handler must repeatedly call `waitpid` (or one of the other related functions) with the `WNOHANG` option until `waitpid` returns zero.

- page 73

  In the first paragraph, the second argument is for `pthread_key_create`, not `pthread_key_t`. Thus, the `pthread_key_create` function takes two arguments: a pointer to a `pthread_key_t` variable and a cleanup function.

- page 98

  The example code for calling `shmget` should use `S_IWUSR`, not `S_IWUSER`. This write permission flag is spelled correctly throughout the rest of the page. For a list of available flags, see the section 2 `stat` man page.

- page 108

  In Listing 5.6, the function used to parse the string should be `sscanf`, not `scanf`.

- page 110

  The last sentence of section 5.4.1 should read:

  > Data written to the file descriptor `write_fd` can be read back from `read_fd`.

  The identifiers `write_fd` and `read_fd` are swapped in the text as printed.

- page 117

  In section 5.5.2, the list of system calls should mention `close`, not `closes`.

- page 120

  In Listing 5.10, `text` should be checked for the `quit` message before it is freed. The consequent of the `strcmp` should be `free (text); return 1`. Its alternative should be `free (text)`. The standalone `free` statement should be omitted.

- page 121

  In Listing 5.10, the `client_name_len` variable in the `do`-loop should be initialized to `sizeof(client_name)` before being passed to `accept`.

- page 121

  In Listing 5.10, the call to `bind` on the ninth line of this page should cast the second argument to a `struct sockaddr *`. That is, the `bind` call should be

  > `bind (socket_fd, (struct sockaddr *) &name, SUN_LEN (&name))`.

  Similarly, on the nineteenth line, the second argument of `accept` should be cast:

  > `accept (socket_fd, (struct sockaddr *) &client_name, &client_name_len)`

- page 122

  In Listing 5.11, the call to `connect` on the sixth line from the end should cast the second argument to a `struct sockaddr *`. That is, the `connect` call should be

  > `connect (socket_fd, (struct sockaddr *) &name, SUN_LEN (&name))`.

- page 125

  In Listing 5.12, the call to `connect` on the second line should cast the second argument to a `struct sockaddr *`. That is, the `connect` call should be

  > `connect (socket_fd, (struct sockaddr *) &name, sizeof (struct sockaddr_in))`.

- page 130

  The third line of the first full paragraph should omit the word "cause".

- page 132

  The sixth line of the first full paragraph should refer to "the character device", not the "the block device".

- page 133

  In the first footnote, the Windows device name should be `LPT1`, not `LRP1`.

- page 133

  In the second footnote, the ASCII code for a carriage return should be 13, not 14.

- page 149

  The check for whether or not the read failed should be:

  > `if (bytes_read == 0 || bytes_read != sizeof (buffer))`

  Note that the operator for the second half of the conditional should be `!=` rather than `==`.

- page 171

  In the third paragraph, use `F_SETLKW`, not `F_SETLCKW`. This `LK` abbreviation differs from the `LCK` abbreviation in `F_RDLCK` and `F_WRLCK`.

- page 174

  The first sentence of the third paragraph of section 8.5 should end with "pointer to a `struct rlimit`", rather than "pointer to a `structrlimit`" as printed. Note the space between `struct` and `rlimit`.

- page 181

  The description of `tv_nsec` should read "`tv_nsec`, an additional number of nanoseconds" rather than "`tv_nsec`, an additional number of milliseconds."

- page 183

  The third parameter in the call to `readlink` should be `sizeof (target_path) - 1` to allow for the terminating `NUL` character.

- page 185

  The file presented in Listing 8.11 should be named "itimer.c".

- page 186

  The `sysinfo` manual page describes `struct sysinfo`, not `structsysinfo`.

- page 188

  The file presented in Listing 8.11 should end with a ".c", i.e., "print-uname.c".

- page 191

  The assembly instructions shown corresponding to the `asm` should be:

  >     #APP
  >             mycool_asm %ecx, %edx
  >     #NOAPP

  reflecting the fact that `foo` and `bar` are in separate registers.

- page 206

  In the beginning of 10.4.1, the root process impersonates another user, not another process.

- page 212

  The prototype of the GNU extension `getline` function differs from that presented. To use the GNU extension, modify the code to

       char *username = NULL;
       size_t username_length = 0;
       ssize_t characters_read = getline (&username, &username_length, stdin);

  If the call fails, `characters_read` will be `-1`. Otherwise, `username` will point to a `malloc`-allocated buffer with `username_length` characters.

- page 224

  The third parameter in the call to `readlink` should be `sizeof (link_target) - 1` to allow for the terminating `NUL` character.

- page 231

  The third parameter in the first call to `write` should be `strlen (bad_request_response)`.

- page 241

  The `error_page` string should note a failure to open `/etc/issue`, not `/proc/issue`.

- page 245

  The comment above the `get_group_name` function should say "deallocate with free", not "allocate with free".

- page 286

  The first line inside the while loop is incorrect. It should read:

  > size_t written = write (fd, buffer + count - left_to_write, left_to_write);

Problems with this web site? File an issue on github.