1152832Sdavidxu/* $FreeBSD: stable/11/tests/sys/mqueue/mqtest3.c 306905 2016-10-09 12:34:56Z kib $ */ 2205225Skib 3205225Skib#include <sys/types.h> 4205225Skib#include <sys/select.h> 5205225Skib#include <sys/wait.h> 6205225Skib#include <err.h> 7205225Skib#include <fcntl.h> 8152832Sdavidxu#include <mqueue.h> 9152832Sdavidxu#include <signal.h> 10205225Skib#include <stdio.h> 11205225Skib#include <stdlib.h> 12152832Sdavidxu#include <unistd.h> 13152832Sdavidxu 14282137Sngie#include "freebsd_test_suite/macros.h" 15282137Sngie 16152832Sdavidxu#define MQNAME "/mytstqueue3" 17152832Sdavidxu#define LOOPS 1000 18152832Sdavidxu#define PRIO 10 19152832Sdavidxu 20281428Sngiestatic void 21281428Sngiesighandler(int sig __unused) 22152832Sdavidxu{ 23152832Sdavidxu write(1, "timeout\n", 8); 24152832Sdavidxu _exit(1); 25152832Sdavidxu} 26152832Sdavidxu 27281428Sngieint 28281428Sngiemain(void) 29152832Sdavidxu{ 30281428Sngie fd_set set; 31281428Sngie struct mq_attr attr; 32281428Sngie int status; 33165829Sdavidxu mqd_t mq; 34281428Sngie pid_t pid; 35152832Sdavidxu 36282137Sngie PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); 37282137Sngie 38152832Sdavidxu mq_unlink(MQNAME); 39152832Sdavidxu 40152832Sdavidxu attr.mq_maxmsg = 5; 41152832Sdavidxu attr.mq_msgsize = 128; 42152832Sdavidxu mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr); 43165829Sdavidxu if (mq == (mqd_t)-1) 44152832Sdavidxu err(1, "mq_open()"); 45152832Sdavidxu status = mq_getattr(mq, &attr); 46152832Sdavidxu if (status) 47152832Sdavidxu err(1, "mq_getattr()"); 48152832Sdavidxu 49152832Sdavidxu pid = fork(); 50152832Sdavidxu if (pid == 0) { /* child */ 51152832Sdavidxu char *buf; 52281428Sngie int j, i; 53281428Sngie unsigned int prio; 54152832Sdavidxu 55152832Sdavidxu mq_close(mq); 56152832Sdavidxu 57152832Sdavidxu signal(SIGALRM, sighandler); 58152832Sdavidxu 59152832Sdavidxu mq = mq_open(MQNAME, O_RDWR); 60165829Sdavidxu if (mq == (mqd_t)-1) 61152832Sdavidxu err(1, "child process: mq_open"); 62152832Sdavidxu buf = malloc(attr.mq_msgsize); 63152832Sdavidxu for (j = 0; j < LOOPS; ++j) { 64152832Sdavidxu FD_ZERO(&set); 65306905Skib FD_SET(mq_getfd_np(mq), &set); 66152832Sdavidxu alarm(3); 67306905Skib status = select(mq_getfd_np(mq) + 1, &set, NULL, 68306905Skib NULL, NULL); 69152832Sdavidxu if (status != 1) 70152832Sdavidxu err(1, "child process: select()"); 71152832Sdavidxu status = mq_receive(mq, buf, attr.mq_msgsize, &prio); 72152832Sdavidxu if (status == -1) 73152832Sdavidxu err(2, "child process: mq_receive"); 74152832Sdavidxu for (i = 0; i < attr.mq_msgsize; ++i) 75152832Sdavidxu if (buf[i] != i) 76152832Sdavidxu err(3, "message data corrupted"); 77152832Sdavidxu if (prio != PRIO) 78152832Sdavidxu err(4, "priority is incorrect: %d", prio); 79152832Sdavidxu } 80152832Sdavidxu alarm(0); 81152832Sdavidxu free(buf); 82152832Sdavidxu mq_close(mq); 83152832Sdavidxu return (0); 84152832Sdavidxu } else if (pid == -1) { 85152832Sdavidxu err(1, "fork()"); 86152832Sdavidxu } else { 87152832Sdavidxu char *buf; 88281428Sngie int i, j; 89152832Sdavidxu 90152832Sdavidxu signal(SIGALRM, sighandler); 91152832Sdavidxu buf = malloc(attr.mq_msgsize); 92152832Sdavidxu for (j = 0; j < LOOPS; ++j) { 93152832Sdavidxu for (i = 0; i < attr.mq_msgsize; ++i) { 94152832Sdavidxu buf[i] = i; 95152832Sdavidxu } 96152832Sdavidxu alarm(3); 97152832Sdavidxu FD_ZERO(&set); 98306905Skib FD_SET(mq_getfd_np(mq), &set); 99306905Skib status = select(mq_getfd_np(mq) + 1, NULL, &set, 100306905Skib NULL, NULL); 101152832Sdavidxu if (status != 1) 102152832Sdavidxu err(1, "select()"); 103152832Sdavidxu status = mq_send(mq, buf, attr.mq_msgsize, PRIO); 104152832Sdavidxu if (status) { 105152832Sdavidxu kill(pid, SIGKILL); 106152832Sdavidxu err(2, "mq_send()"); 107152832Sdavidxu } 108152832Sdavidxu } 109152832Sdavidxu alarm(3); 110152832Sdavidxu wait(&status); 111152832Sdavidxu alarm(0); 112152832Sdavidxu } 113152832Sdavidxu status = mq_close(mq); 114152832Sdavidxu if (status) 115152832Sdavidxu err(1, "mq_close"); 116152832Sdavidxu mq_unlink(MQNAME); 117152832Sdavidxu return (0); 118152832Sdavidxu} 119