1314818Sngie/* $NetBSD: t_mqueue.c,v 1.6 2017/01/14 20:57:24 christos Exp $ */ 2272343Sngie 3272343Sngie/* 4272343Sngie * Test for POSIX message queue priority handling. 5272343Sngie * 6272343Sngie * This file is in the Public Domain. 7272343Sngie */ 8272343Sngie 9290913Sngie#include <sys/stat.h> 10290913Sngie 11272343Sngie#include <atf-c.h> 12314818Sngie#include <errno.h> 13314818Sngie#include <fcntl.h> 14314818Sngie#include <mqueue.h> 15272343Sngie#include <stdio.h> 16272343Sngie#include <stdlib.h> 17272343Sngie#include <string.h> 18272343Sngie#include <unistd.h> 19272343Sngie 20314818Sngie#ifdef __FreeBSD__ 21314818Sngie#include "freebsd_test_suite/macros.h" 22314818Sngie#endif 23272343Sngie 24272343Sngie#define MQ_PRIO_BASE 24 25272343Sngie 26272343Sngiestatic void 27272343Sngiesend_msgs(mqd_t mqfd) 28272343Sngie{ 29272343Sngie char msg[2]; 30272343Sngie 31272343Sngie msg[1] = '\0'; 32272343Sngie 33272343Sngie msg[0] = 'a'; 34272343Sngie ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1, 35272343Sngie "mq_send 1 failed: %d", errno); 36272343Sngie 37272343Sngie msg[0] = 'b'; 38272343Sngie ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1, 39272343Sngie "mq_send 2 failed: %d", errno); 40272343Sngie 41272343Sngie msg[0] = 'c'; 42272343Sngie ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1, 43272343Sngie "mq_send 3 failed: %d", errno); 44272343Sngie 45272343Sngie msg[0] = 'd'; 46272343Sngie ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1, 47272343Sngie "mq_send 4 failed: %d", errno); 48272343Sngie 49272343Sngie msg[0] = 'e'; 50272343Sngie ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1, 51272343Sngie "mq_send 5 failed: %d", errno); 52272343Sngie 53272343Sngie msg[0] = 'f'; 54272343Sngie ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1, 55272343Sngie "mq_send 6 failed: %d", errno); 56272343Sngie} 57272343Sngie 58272343Sngiestatic void 59272343Sngiereceive_msgs(mqd_t mqfd) 60272343Sngie{ 61272343Sngie struct mq_attr mqa; 62272343Sngie char *m; 63272343Sngie unsigned p; 64272343Sngie int len; 65272343Sngie 66272343Sngie ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d", 67272343Sngie errno); 68272343Sngie 69272343Sngie len = mqa.mq_msgsize; 70272343Sngie m = calloc(1, len); 71272343Sngie ATF_REQUIRE_MSG(m != NULL, "calloc failed"); 72272343Sngie 73272343Sngie ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 74272343Sngie "mq_receive 1 failed: %d", errno); 75272343Sngie ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b', 76272343Sngie "mq_receive 1 prio/data mismatch"); 77272343Sngie 78272343Sngie ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 79272343Sngie "mq_receive 2 failed: %d", errno); 80272343Sngie ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f', 81272343Sngie "mq_receive 2 prio/data mismatch"); 82272343Sngie 83272343Sngie ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 84272343Sngie "mq_receive 3 failed: %d", errno); 85272343Sngie ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a', 86272343Sngie "mq_receive 3 prio/data mismatch"); 87272343Sngie 88272343Sngie ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 89272343Sngie "mq_receive 4 failed: %d", errno); 90272343Sngie ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c', 91272343Sngie "mq_receive 4 prio/data mismatch"); 92272343Sngie 93272343Sngie ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 94272343Sngie "mq_receive 5 failed: %d", errno); 95272343Sngie ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd', 96272343Sngie "mq_receive 5 prio/data mismatch"); 97272343Sngie 98272343Sngie ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 99272343Sngie "mq_receive 6 failed: %d", errno); 100272343Sngie ATF_REQUIRE_MSG(p == 0 && m[0] == 'e', 101272343Sngie "mq_receive 6 prio/data mismatch"); 102272343Sngie} 103272343Sngie 104272343SngieATF_TC(mqueue); 105272343SngieATF_TC_HEAD(mqueue, tc) 106272343Sngie{ 107272343Sngie 108272343Sngie atf_tc_set_md_var(tc, "timeout", "3"); 109272343Sngie atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive"); 110272343Sngie} 111272343Sngie 112272343SngieATF_TC_BODY(mqueue, tc) 113272343Sngie{ 114272343Sngie int status; 115272343Sngie char *tmpdir; 116272343Sngie char template[32]; 117272343Sngie char mq_name[64]; 118272343Sngie 119290913Sngie#ifdef __FreeBSD__ 120290913Sngie ATF_REQUIRE_KERNEL_MODULE("mqueuefs"); 121290913Sngie#endif 122290913Sngie 123272343Sngie strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template)); 124272343Sngie tmpdir = mkdtemp(template); 125272343Sngie ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno); 126290913Sngie#ifdef __FreeBSD__ 127290913Sngie snprintf(mq_name, sizeof(mq_name), "/t_mqueue"); 128290913Sngie#else 129272343Sngie snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir); 130290913Sngie#endif 131272343Sngie 132272343Sngie mqd_t mqfd; 133272343Sngie 134272343Sngie mqfd = mq_open(mq_name, O_RDWR | O_CREAT, 135272343Sngie S_IRUSR | S_IRWXG | S_IROTH, NULL); 136290913Sngie#ifdef __FreeBSD__ 137290913Sngie ATF_REQUIRE_MSG(mqfd != (mqd_t)-1, "mq_open failed: %d", errno); 138290913Sngie#else 139272343Sngie ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno); 140290913Sngie#endif 141272343Sngie 142272343Sngie send_msgs(mqfd); 143272343Sngie receive_msgs(mqfd); 144272343Sngie 145272343Sngie status = mq_close(mqfd); 146272343Sngie ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno); 147272343Sngie} 148272343Sngie 149272343SngieATF_TP_ADD_TCS(tp) 150272343Sngie{ 151272343Sngie ATF_TP_ADD_TC(tp, mqueue); 152272343Sngie 153272343Sngie return atf_no_error(); 154272343Sngie} 155