1152832Sdavidxu/* $FreeBSD: releng/10.3/tests/sys/mqueue/mqtest3.c 282858 2015-05-13 12:09:01Z ngie $ */ 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 14282858Sngie#include "freebsd_test_suite/macros.h" 15282858Sngie 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 36282858Sngie PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); 37282858Sngie 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); 65165829Sdavidxu FD_SET(__mq_oshandle(mq), &set); 66152832Sdavidxu alarm(3); 67165829Sdavidxu status = select(__mq_oshandle(mq)+1, &set, NULL, NULL, NULL); 68152832Sdavidxu if (status != 1) 69152832Sdavidxu err(1, "child process: select()"); 70152832Sdavidxu status = mq_receive(mq, buf, attr.mq_msgsize, &prio); 71152832Sdavidxu if (status == -1) 72152832Sdavidxu err(2, "child process: mq_receive"); 73152832Sdavidxu for (i = 0; i < attr.mq_msgsize; ++i) 74152832Sdavidxu if (buf[i] != i) 75152832Sdavidxu err(3, "message data corrupted"); 76152832Sdavidxu if (prio != PRIO) 77152832Sdavidxu err(4, "priority is incorrect: %d", prio); 78152832Sdavidxu } 79152832Sdavidxu alarm(0); 80152832Sdavidxu free(buf); 81152832Sdavidxu mq_close(mq); 82152832Sdavidxu return (0); 83152832Sdavidxu } else if (pid == -1) { 84152832Sdavidxu err(1, "fork()"); 85152832Sdavidxu } else { 86152832Sdavidxu char *buf; 87281428Sngie int i, j; 88152832Sdavidxu 89152832Sdavidxu signal(SIGALRM, sighandler); 90152832Sdavidxu buf = malloc(attr.mq_msgsize); 91152832Sdavidxu for (j = 0; j < LOOPS; ++j) { 92152832Sdavidxu for (i = 0; i < attr.mq_msgsize; ++i) { 93152832Sdavidxu buf[i] = i; 94152832Sdavidxu } 95152832Sdavidxu alarm(3); 96152832Sdavidxu FD_ZERO(&set); 97165829Sdavidxu FD_SET(__mq_oshandle(mq), &set); 98165829Sdavidxu status = select(__mq_oshandle(mq)+1, NULL, &set, NULL, NULL); 99152832Sdavidxu if (status != 1) 100152832Sdavidxu err(1, "select()"); 101152832Sdavidxu status = mq_send(mq, buf, attr.mq_msgsize, PRIO); 102152832Sdavidxu if (status) { 103152832Sdavidxu kill(pid, SIGKILL); 104152832Sdavidxu err(2, "mq_send()"); 105152832Sdavidxu } 106152832Sdavidxu } 107152832Sdavidxu alarm(3); 108152832Sdavidxu wait(&status); 109152832Sdavidxu alarm(0); 110152832Sdavidxu } 111152832Sdavidxu status = mq_close(mq); 112152832Sdavidxu if (status) 113152832Sdavidxu err(1, "mq_close"); 114152832Sdavidxu mq_unlink(MQNAME); 115152832Sdavidxu return (0); 116152832Sdavidxu} 117