Errata

POSIX.4 Programmers Guide

Errata for POSIX.4 Programmers Guide

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
Printed Page 2
492~493

<source error >

#define _POSIX_C_SOURCE 199309
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <mqueue.h>
#include <errno.h>

int nreads = 0, nwrites = 0;
pid_t chpid, parentpid;

char *progname;
char *whoami;

#define DEFAULT_NBYTES 4
int nbytes = DEFAULT_NBYTES;

#define MQ_ONE "/mq_one"
#define MQ_TWO "/mq_two"

char *buf;

void
usage()
{
printf("Usage: %s {nbytes} (default nbytes is %d)en",
progname, DEFAULT_NBYTES);
exit(1);
}

main(int argc, char **argv)
{
int i;
struct sigaction sa;
extern void alarm_handler(int);
mqd_t m1, m2;
struct mq_attr ma;

progname = argv[0];

if (argc == 2) {
nbytes = atoi(argv[1]);
} else if (argc > 2) {
usage();
}

printf("Testing IPC through POSIX.4 mqs using %d-byte sends/recvsen",
nbytes);

if ((buf = (char *)malloc(nbytes)) == NULL) {
perror("malloc");
exit(1);
}

/* Set up signals used for terminating the experiment */
sigfillset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = alarm_handler; /* Terminates experiment */
if (sigaction(SIGALRM, &sa, NULL) < 0) {
perror("sigaction SIGALRM");
exit(1);
}

/* Create some message queues */
ma.mq_flags = 0; /* No special behavior */
ma.mq_maxmsg = 1;
ma.mq_msgsize = nbytes;
i = mq_unlink(MQ_ONE); /* Deal with possible leftovers */
if ((i < 0) && (errno != ENOENT)) {
perror("mq_unlink");
exit(1);
}
i = mq_unlink(MQ_TWO); /* Deal with possible leftovers */
if ((i < 0) && (errno != ENOENT)) {
perror("mq_unlink");
exit(1);
}
if ((m1 = mq_open(MQ_ONE, O_CREAT|O_EXCL, MODE, &ma)) < 0) {
perror("mq_open");
exit(1);
}
if (pipe(pe2) < 0) {
perror("pipe");
exit(1);
}

/* Duplicate the process */
switch (chpid = fork()) {
case -1: /* error */
perror("fork");
exit(2);
break;
case 0: /* child */
whoami = "child";
be_a_child(pe1[WRITE_END], pe2[READ_END]);
exit(0);
break;
default: /* parent */
whoami = "parent";
be_the_parent(pe2[WRITE_END], pe1[READ_END]);
exit(0);
break;
}

fprintf(stderr, "Unexpected exit from test program!en");
exit(3);
}

be_a_child(int write_this, int read_this)
{
int ret;

while (1) {
if ((ret=read(read_this, buf, nbytes)) != nbytes) {
printf("Returned %d bytes trying to read %den", ret, nbytes);
perror("child read from pipe");
exit(1);
}
nreads++;
if (write(write_this, buf, nbytes) != nbytes) {
perror("child write to pipe");
exit(1);
}
nwrites++;
}
}

be_the_parent(int write_this, int read_this)
{
alarm(60);
while (1) {
if (write(write_this, buf, nbytes) != nbytes) {
perror("parent write to pipe");
exit(1);
}
nwrites++;
if (read(read_this, buf, nbytes) != nbytes) {
perror("parent read from pipe");
exit(1);
}
nreads++;
}
}

void alarm_handler(int signo)
{
printf("%d/%d reads/writes (%d bytes each) by %s (%d bytes sent/sec)en",
nreads, nwrites, nbytes, whoami, (nwrites * nbytes) / 60);
if (getpid() != chpid) /* Parent--kill child too */
kill(chpid, SIGALRM);
exit(0);

}

Anonymous   
Printed Page 29
have_asynchio method example

Very trivial problem, but your function

have_asynchio

doesn't return a value if _POSIX_ASYNCHRONOUS_IO is defined.

Anonymous   
Printed Page 32
2nd last line

_POSIX_SYNCHRONIZED_IO is not a valid pathconf() Option.

In the example, 'opt' must be set to one of the Options listed in Table
2-7. For example,
opt = _PC_SYNC_IO;

Anonymous   
Printed Page 66
source code example

The SIG_QUERY_COMPLETE signal is masked in the signal set "wait_for_these,"
thus the system call :

sigsuspend(&wait_for_these) does not work !

It is OK to mask the signal with sigprocmask(...) before sigsuspend(), but the
signal has to be unblocked during the system call, removed from the signals
present in the signal set.

So, before the while (1):

sigdelset(&wait_for_these, SIG_QUERY_COMPLETE);

Also see example given in the GNU C library :
('usr_interrupt' is set in the awaited signal handler)
/* Wait for a signal to arrive. */
sigprocmask (SIG_BLOCK, &mask, &oldmask);
while (!usr_interrupt)
sigsuspend (&oldmask);
sigprocmask (SIG_UNBLOCK, &mask, NULL);

Anonymous   
Printed Page 124
code listed for child process

The shm_open statement is missing an argument, e.g.,

shm_open(SHM_AREA_NAME, O_RDWR);

Instead, it should be someting like:

shm_open(SHM_AREA_NAME, O_RDWR, S_IRWXU);

I have also found other pages where shm_open was missing the last argument.
Please see pages 126, 127 and 118.

Anonymous   
Printed Page 190
Last line

The maximum value for a 32-bit two-complement integer should be 2^31 - 1, not 2^-331 - 1.

Gabe Jones  Aug 21, 2009 
Printed Page 191
Code comments at bottom of page

"detemrine" => "determine"

Gabe Jones  Aug 21, 2009 
Printed Page 472
3rd paragraph of "description"

If new_setting->it_value is 0, then timer disarms ...

Note: it_value is a struct timespec {time_t ..., long ...}

Consider using the following to disarm timer:

new_setting->it_value.tv_sec = 0

and

new_setting->it_value.tv_nsec = 0

Anonymous