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