1 2 #include <sys/types.h> 3 #include <sys/event.h> 4 #include <sys/select.h> 5 #include <sys/wait.h> 6 #include <err.h> 7 #include <fcntl.h> 8 #include <mqueue.h> 9 #include <signal.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <unistd.h> 13 14 #define MQNAME "/mytstqueue5" 15 #define LOOPS 1000 16 #define PRIO 10 17 18 static void 19 sighandler(int sig __unused) 20 { 21 write(1, "timeout\n", 8); 22 _exit(1); 23 } 24 25 int 26 main(void) 27 { 28 int status; 29 struct mq_attr attr; 30 struct sigaction sa; 31 sigset_t set; 32 siginfo_t info; 33 mqd_t mq; 34 pid_t pid; 35 36 mq_unlink(MQNAME); 37 38 sigemptyset(&set); 39 sigaddset(&set, SIGRTMIN); 40 sigprocmask(SIG_BLOCK, &set, NULL); 41 sigemptyset(&sa.sa_mask); 42 sa.sa_flags = SA_SIGINFO; 43 sa.sa_sigaction = (void *) SIG_DFL; 44 sigaction(SIGRTMIN, &sa, NULL); 45 46 attr.mq_maxmsg = 5; 47 attr.mq_msgsize = 128; 48 mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr); 49 if (mq == (mqd_t)-1) 50 err(1, "mq_open()"); 51 status = mq_getattr(mq, &attr); 52 if (status) 53 err(1, "mq_getattr()"); 54 pid = fork(); 55 if (pid == 0) { /* child */ 56 int prio, j, i; 57 char *buf; 58 struct sigevent sigev; 59 60 signal(SIGALRM, sighandler); 61 62 sigev.sigev_notify = SIGEV_SIGNAL; 63 sigev.sigev_signo = SIGRTMIN; 64 sigev.sigev_value.sival_int = 2; 65 66 mq_close(mq); 67 mq = mq_open(MQNAME, O_RDWR | O_NONBLOCK); 68 if (mq == (mqd_t)-1) 69 err(1, "child: mq_open"); 70 buf = malloc(attr.mq_msgsize); 71 for (j = 0; j < LOOPS; ++j) { 72 alarm(3); 73 status = mq_notify(mq, &sigev); 74 if (status) 75 err(1, "child: mq_notify"); 76 status = sigwaitinfo(&set, &info); 77 if (status == -1) 78 err(1, "child: sigwaitinfo"); 79 if (info.si_value.sival_int != 2) 80 err(1, "child: sival_int"); 81 status = mq_receive(mq, buf, attr.mq_msgsize, &prio); 82 if (status == -1) 83 err(2, "child: mq_receive"); 84 for (i = 0; i < attr.mq_msgsize; ++i) 85 if (buf[i] != i) 86 err(3, "child: message data corrupted"); 87 if (prio != PRIO) 88 err(4, "child: priority is incorrect: %d", 89 prio); 90 } 91 alarm(0); 92 free(buf); 93 mq_close(mq); 94 return (0); 95 } else if (pid == -1) { 96 err(1, "fork()"); 97 } else { 98 char *buf; 99 int i, j; 100 101 signal(SIGALRM, sighandler); 102 buf = malloc(attr.mq_msgsize); 103 for (j = 0; j < LOOPS; ++j) { 104 for (i = 0; i < attr.mq_msgsize; ++i) { 105 buf[i] = i; 106 } 107 alarm(3); 108 status = mq_send(mq, buf, attr.mq_msgsize, PRIO); 109 if (status) { 110 kill(pid, SIGKILL); 111 err(2, "mq_send()"); 112 } 113 } 114 alarm(3); 115 wait(&status); 116 alarm(0); 117 } 118 status = mq_close(mq); 119 if (status) 120 err(1, "mq_close"); 121 mq_unlink(MQNAME); 122 return (0); 123 } 124