| 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 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 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 |