1204076Spjd/* $FreeBSD$ */ 2204076Spjd 3204076Spjd#include <sys/types.h> 4204076Spjd#include <sys/event.h> 5204076Spjd#include <sys/select.h> 6204076Spjd#include <sys/wait.h> 7204076Spjd#include <err.h> 8204076Spjd#include <fcntl.h> 9204076Spjd#include <mqueue.h> 10204076Spjd#include <signal.h> 11204076Spjd#include <stdio.h> 12204076Spjd#include <stdlib.h> 13204076Spjd#include <unistd.h> 14204076Spjd 15204076Spjd#include "freebsd_test_suite/macros.h" 16204076Spjd 17204076Spjd#define MQNAME "/mytstqueue5" 18204076Spjd#define LOOPS 1000 19204076Spjd#define PRIO 10 20204076Spjd 21204076Spjdstatic void 22204076Spjdsighandler(int sig __unused) 23204076Spjd{ 24204076Spjd write(1, "timeout\n", 8); 25204076Spjd _exit(1); 26204076Spjd} 27204076Spjd 28204076Spjdint 29204076Spjdmain(void) 30204076Spjd{ 31204076Spjd int status; 32204076Spjd struct mq_attr attr; 33204076Spjd struct sigaction sa; 34204076Spjd sigset_t set; 35204076Spjd siginfo_t info; 36204076Spjd mqd_t mq; 37204076Spjd pid_t pid; 38204076Spjd 39204076Spjd PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); 40204076Spjd 41204076Spjd mq_unlink(MQNAME); 42204076Spjd 43229509Strociny sigemptyset(&set); 44204076Spjd sigaddset(&set, SIGRTMIN); 45229509Strociny sigprocmask(SIG_BLOCK, &set, NULL); 46229509Strociny sigemptyset(&sa.sa_mask); 47229509Strociny sa.sa_flags = SA_SIGINFO; 48229509Strociny sa.sa_sigaction = (void *) SIG_DFL; 49229509Strociny sigaction(SIGRTMIN, &sa, NULL); 50229509Strociny 51229509Strociny attr.mq_maxmsg = 5; 52204076Spjd attr.mq_msgsize = 128; 53204076Spjd mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr); 54204076Spjd if (mq == (mqd_t)-1) 55219864Spjd err(1, "mq_open()"); 56204076Spjd status = mq_getattr(mq, &attr); 57204076Spjd if (status) 58204076Spjd err(1, "mq_getattr()"); 59204076Spjd pid = fork(); 60204076Spjd if (pid == 0) { /* child */ 61204076Spjd int prio, j, i; 62204076Spjd char *buf; 63204076Spjd struct sigevent sigev; 64204076Spjd 65204076Spjd signal(SIGALRM, sighandler); 66204076Spjd 67204076Spjd sigev.sigev_notify = SIGEV_SIGNAL; 68204076Spjd sigev.sigev_signo = SIGRTMIN; 69204076Spjd sigev.sigev_value.sival_int = 2; 70204076Spjd 71204076Spjd mq_close(mq); 72204076Spjd mq = mq_open(MQNAME, O_RDWR | O_NONBLOCK); 73204076Spjd if (mq == (mqd_t)-1) 74204076Spjd err(1, "child: mq_open"); 75204076Spjd buf = malloc(attr.mq_msgsize); 76204076Spjd for (j = 0; j < LOOPS; ++j) { 77204076Spjd alarm(3); 78204076Spjd status = mq_notify(mq, &sigev); 79204076Spjd if (status) 80204076Spjd err(1, "child: mq_notify"); 81204076Spjd status = sigwaitinfo(&set, &info); 82204076Spjd if (status == -1) 83204076Spjd err(1, "child: sigwaitinfo"); 84204076Spjd if (info.si_value.sival_int != 2) 85204076Spjd err(1, "child: sival_int"); 86204076Spjd status = mq_receive(mq, buf, attr.mq_msgsize, &prio); 87204076Spjd if (status == -1) 88204076Spjd err(2, "child: mq_receive"); 89204076Spjd for (i = 0; i < attr.mq_msgsize; ++i) 90204076Spjd if (buf[i] != i) 91204076Spjd err(3, "child: message data corrupted"); 92204076Spjd if (prio != PRIO) 93204076Spjd err(4, "child: priority is incorrect: %d", 94204076Spjd prio); 95204076Spjd } 96204076Spjd alarm(0); 97204076Spjd free(buf); 98204076Spjd mq_close(mq); 99204076Spjd return (0); 100204076Spjd } else if (pid == -1) { 101204076Spjd err(1, "fork()"); 102229509Strociny } else { 103204076Spjd char *buf; 104229509Strociny int i, j; 105204076Spjd 106204076Spjd signal(SIGALRM, sighandler); 107204076Spjd buf = malloc(attr.mq_msgsize); 108204076Spjd for (j = 0; j < LOOPS; ++j) { 109204076Spjd for (i = 0; i < attr.mq_msgsize; ++i) { 110204076Spjd buf[i] = i; 111204076Spjd } 112204076Spjd alarm(3); 113229509Strociny status = mq_send(mq, buf, attr.mq_msgsize, PRIO); 114204076Spjd if (status) { 115229509Strociny kill(pid, SIGKILL); 116204076Spjd err(2, "mq_send()"); 117204076Spjd } 118204076Spjd } 119204076Spjd alarm(3); 120204076Spjd wait(&status); 121204076Spjd alarm(0); 122204076Spjd } 123204076Spjd status = mq_close(mq); 124204076Spjd if (status) 125204076Spjd err(1, "mq_close"); 126204076Spjd mq_unlink(MQNAME); 127204076Spjd return (0); 128204076Spjd} 129204076Spjd