getpeername() man page example again (I know!) [book v3.0.7 p. 96]:
replaced AF_INET with AF_INET6 where appropriate. How many bugs can I
have in 10 lines of code? I wrote a short program that counted exactly
how many bugs I had, and it was this: -37! Thanks again to Rafael who
won't let me off the hook until I get it right. :)

I also changed and added some comments in the same example [book v3.0.7
pp. 80-81]. The "proper" way doesn't demonstrate error checking, so
it's not very proper.

// proper way of doing things with getaddrinfo()
// modern way of doing things with getaddrinfo()
[... snip ...]
// make a socket:
// (you should actually walk the "res" linked list and error-check!)

3.0.11, 2009-02-24

Section 5.2 socket() syscall example [book v3.0.7 p. 25]: forgot to
declare the type of hints. Also added a clarifying comment about the
proper use of the getaddrinfo() results linked list. (This bug caught by
Kaio—thanks, as always!)

struct addrinfo *res;
struct addrinfo hints, *res;

and

// do the lookup
// [pretend we already filled out the "hints" struct]
getaddrinfo("www.example.com", "http", &hints, &res);
// [again, you should do error-checking on getaddrinfo(), and walk
// the "res" linked list looking for valid entries instead of just
// assuming the first one is good (like many of these examples do.)
// See the section on client/server for real examples.]

3.0.12, 2009-02-24

And the hits just keep coming today! These are from Mick—a
couple of typos.

Section 3.1, "IP Addresses, versions 4 and 6" [book v3.0.7 p. 9]:

and was common written in "dots and numbers" form
and was commonly written in "dots and numbers" form

And, same section [book v3.0.7 p. 10]:

That we need not just twice as many address, not a billion times as many
That we need not just twice as many addresses, not a billion times as many

3.0.13, 2009-03-23

A big batch today from Rainer Kupke: "&amp;" removals and a
quick note about using errno in multithreaded environments.
couple of typos. Hopefully this is all the stupid &amp; errors caused
by my lame indiscriminate use of CDATA in my source XML...

The global variable errno is set to the error's value (see the perror()
man page.)
The global variable errno is set to the error's value (see the errno
man page for more details, and a quick note on using errno in
multithreaded programs.)

Section 9.10, "errno" [book v3.0.7 p 97], add the following paragraph to the
end of the description:

One thing to note, for you multithreading enthusiasts, is that on most systems
errno is defined in a threadsafe manner. (That is, it's not actually a
global variable, but it behaves just like a global variable would in a
single-threaded environment.)

This being said, in modern times select(), though very
portable, is one of the slowest methods for monitoring sockets. One
possible alternative is libevent, or something similar, that
encapsulates all the system-dependent stuff involved with getting socket
notifications.
Without any further ado, I'll offer the synopsis of select():

Section 7.4, "Serialization—How to Pack Data" [book v3.0.7 pp.
58-62]: multitude of changes, too many to list, to pack2.c to get it to function properly on 32-bit
and 64-bit machines. It now relies on C99 features, but it was the
cleanest way to get it portable. Modern gcc
should have no trouble. (Thanks to Bruce L. for the catch and
testing.)

[THE END]
(Before I begin this section in earnest, I should tell you that there
are libraries out there for doing this, and rolling your own and
remaining portable and error-free is quite a challenge. So hunt around
and do your homework before deciding to implement this stuff yourself.
I include the information here for those curious about how things like
this work.)
Actually all the methods, above, have their drawbacks and advantages,

But if you want your source code to be portable, that's an assumption
you can't necessarily make. (On the other hand, if you want things to
be fast, you should optimize this out on platforms that don't need to do
it! That's what htons() and its ilk do.)

In Section 5.1, "getaddrinfo()—Prepare to launch!",
the following was added to showip.c:

#include <netinet/in.h>

In the setsockopt/getsockopt man page, the incorrect instructions
about optval were corrected:

The final parameter, optlen, should be set to the length
of optval, probably sizeof(int), but varies
depending on the option. Note that in the case of
getsockopt(), this is a pointer to a
socklen_t, and it specifies the maximum size object that
will be stored in optval (to prevent buffer overflows). And
getsockopt() will modify the value of optlen to
reflect the number of bytes actually set.

In server.c, move the freeaddrinfo() call to before
the error checking:

In Section 6.1, remove the "\n", since the code doesn't actually send
that.

All this server does is send the string "Hello, world!"
out over a stream connection. All you need to do to test this server is
run it in one window, and telnet to it from another with:

In 9.24 "struct sockaddr and pals", added missing # to
include:

#include <netinet/in.h>

In 3.1.1 Subnets, do proper math on 224:

And now for more outdated information! Ready? In the Ancient Times,
there were "classes" of subnets, where the first one, two, or three
bytes of the address was the network part. If you were lucky enough to
have one byte for the network and three for the host, you could have 24
bits-worth of hosts on your network (16 million or so). That was
a "Class A" network. On the opposite end was a "Class C", with three
bytes of network, and one byte of host (256 hosts, minus a couple that
were reserved.)

If you try to read from a non-blocking socket and there's no data there,
it's not allowed to block—it will return -1 and errno will be set to
EAGAIN or EWOULDBLOCK.
(Wait—it can return EAGAIN or EWOULDBLOCK? Which do you check for?
The specification doesn't actually specify which your system will
return, so for portability, check them both.)

In 3.4.1 Private (Or Disconnected) Networks, remove bad apostrophe:

But if I ask my local computer what its IP address is, it says
10.0.0.5.

(Also, all the code written before struct addrinfo was invented
we packed all this stuff by hand, so you'll see a lot of IPv4
code out in the wild that does exactly that. You know, in old versions
of this guide and so on.)

In 5.2 socket(), fix article:

Now, get some milk and cookies, because it's times for a story. Once
upon a time, a long time ago, it was thought that maybe an
address family

In 9.5 getaddrinfo(), fix typo:

This is really where you get to define what the getaddrinfo()
function is going to do.

In 9.14 inet_ntop(), fix the same typo:

These functions don't do DNS lookups—you'll need getaddrinfo()
for that.

In 9.24 struct sockaddr and pals, fix the same typo again:

Often you'll use getaddrinfo() to fill these structures out, and
then will read them when you have to.

In 7.4 Serialization, fix signed char unpacking in unpack()
See, I told you not to roll your own!! :-)

Returns a pointer to a resultant struct hostent on success, or NULL on
error.

3.0.18, 2016-01-05

In 9.5. getaddrinfo(), freeaddrinfo(), gai_strerror(); also in
client.c: reversed close() and perror() calls so the
perror would refer to the right syscall.

perror("connect");
close(sockfd);

3.0.19, 2016-02-08

In 7.2. select()--Asynchronous I/O Multiplexing, added this
paragraph to the end:

Quick note to all you Linux fans out there: sometimes, in rare
circumstances, Linux's select() can return “ready-to-read” and then not
actually be ready to read! This means it will block on the read() after
the select() says it won't! Why you little—! Anyway, the workaround
solution is to set the O_NONBLOCK flag on the receiving socket so it
errors with EWOULDBLOCK (which you can just safely ignore if it occurs).
See the fcntl() reference page for more info on setting a socket to
non-blocking.

In 9.19. select(), added this paragraph to the end:

Note for Linux users: Linux's select() can return “ready-to-read” and
then not actually be ready to read, thus causing the subsequent read()
call to block. You can work around this bug by setting O_NONBLOCK flag
on the receiving socket so it errors with EWOULDBLOCK , then ignoring
this error if it occurs. See the fcntl() reference page for more info on
setting a socket to non-blocking.

3.0.20, 2016-03-11

In 9.17. poll(), added the fd field so that it
works at all:

ufds[1].fd = s2;

3.0.21, 2016-06-08

In 5.3, fixed example to be resistant to Solaris:

if (setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))
if (setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof yes)