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