Should you find an error in Advanced Linux Programming that is not already listed here, please send mail to alp-errata@advancedlinuxprogramming.com.
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/).
The term "GNU/Linux" is misspelled as "GNU/Liux."
In Listing 1.1, add #include <stdlib.h> since atoi is used.
The first paragraph of Section 1.2.2 should refer to reciprocal.cpp, not utilties.cpp.
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.
In the code, the comment for case ENOENT
should
read PATH does not exist
.
The first sentence in Section 2.3.2 should refer to an archive
rather than a archive
.
In the last sentence of the text, omitting the sidebar, the
resulting object file is test1.o
, not test.o
.
In the first paragraph, the linker stops searching directories.
In the paragraph beginning with "Static libraries", modify "If decide to link" to "If you decide to link".
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
.
The indented line of code near the bottom of the page should refer to my_function
, not foo
.
In the first paragraph, the first technique has "considerable risks", not "considerably risks".
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.
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.
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.
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.
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.
In Listing 5.6, the function used to parse the string
should be sscanf
, not scanf
.
The last sentence of section 5.4.1 should read:
Data written to the file descriptorwrite_fd
can be read back fromread_fd
.
The identifiers write_fd
and read_fd
are
swapped in the text as printed.
In section 5.5.2, the list of system calls should mention close, not closes.
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.
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
.
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)
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))
.
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))
.
The third line of the first full paragraph should omit the word "cause".
The sixth line of the first full paragraph should refer to "the character device", not the "the block device".
In the first footnote, the Windows device name should be LPT1
,
not LRP1
.
In the second footnote, the ASCII code for a carriage return should be 13, not 14.
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 ==
.
In the third paragraph, use F_SETLKW
, not F_SETLCKW
. This
LK
abbreviation differs from the LCK
abbreviation in F_RDLCK
and
F_WRLCK
.
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
.
The description of tv_nsec
should read "tv_nsec
,
an additional number of nanoseconds" rather than "tv_nsec
,
an additional number of milliseconds."
The third parameter in the call to readlink
should
be sizeof (target_path) - 1
to allow for the terminating
NUL
character.
The file presented in Listing 8.11 should be named "itimer.c".
The sysinfo
manual page describes struct
sysinfo
, not structsysinfo
.
The file presented in Listing 8.11 should end with a ".c", i.e., "print-uname.c".
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.
In the beginning of 10.4.1, the root process impersonates another user, not another process.
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.
The third parameter in the call to readlink
should
be sizeof (link_target) - 1
to allow for the terminating
NUL
character.
The third parameter in the first call to write
should
be strlen (bad_request_response)
.
The error_page
string should note a failure to
open /etc/issue
, not /proc/issue
.
The comment above the get_group_name function should say "deallocate with free", not "allocate with free".
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. |