1 /* $NetBSD: t_mqueue.c,v 1.4 2014/03/02 19:56:48 jmmv Exp $ */ 2 3 /* 4 * Test for POSIX message queue priority handling. 5 * 6 * This file is in the Public Domain. 7 */ 8 9 #ifdef __FreeBSD__ 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 13 #include "freebsd_test_suite/macros.h" 14 #endif 15 16 #include <atf-c.h> 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <errno.h> 22 #include <unistd.h> 23 24 #include <mqueue.h> 25 26 #define MQ_PRIO_BASE 24 27 28 static void 29 send_msgs(mqd_t mqfd) 30 { 31 char msg[2]; 32 33 msg[1] = '\0'; 34 35 msg[0] = 'a'; 36 ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1, 37 "mq_send 1 failed: %d", errno); 38 39 msg[0] = 'b'; 40 ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1, 41 "mq_send 2 failed: %d", errno); 42 43 msg[0] = 'c'; 44 ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1, 45 "mq_send 3 failed: %d", errno); 46 47 msg[0] = 'd'; 48 ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1, 49 "mq_send 4 failed: %d", errno); 50 51 msg[0] = 'e'; 52 ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1, 53 "mq_send 5 failed: %d", errno); 54 55 msg[0] = 'f'; 56 ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1, 57 "mq_send 6 failed: %d", errno); 58 } 59 60 static void 61 receive_msgs(mqd_t mqfd) 62 { 63 struct mq_attr mqa; 64 char *m; 65 unsigned p; 66 int len; 67 68 ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d", 69 errno); 70 71 len = mqa.mq_msgsize; 72 m = calloc(1, len); 73 ATF_REQUIRE_MSG(m != NULL, "calloc failed"); 74 75 ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 76 "mq_receive 1 failed: %d", errno); 77 ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b', 78 "mq_receive 1 prio/data mismatch"); 79 80 ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 81 "mq_receive 2 failed: %d", errno); 82 ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f', 83 "mq_receive 2 prio/data mismatch"); 84 85 ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 86 "mq_receive 3 failed: %d", errno); 87 ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a', 88 "mq_receive 3 prio/data mismatch"); 89 90 ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 91 "mq_receive 4 failed: %d", errno); 92 ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c', 93 "mq_receive 4 prio/data mismatch"); 94 95 ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 96 "mq_receive 5 failed: %d", errno); 97 ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd', 98 "mq_receive 5 prio/data mismatch"); 99 100 ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, 101 "mq_receive 6 failed: %d", errno); 102 ATF_REQUIRE_MSG(p == 0 && m[0] == 'e', 103 "mq_receive 6 prio/data mismatch"); 104 } 105 106 ATF_TC(mqueue); 107 ATF_TC_HEAD(mqueue, tc) 108 { 109 110 atf_tc_set_md_var(tc, "timeout", "3"); 111 atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive"); 112 } 113 114 ATF_TC_BODY(mqueue, tc) 115 { 116 int status; 117 char *tmpdir; 118 char template[32]; 119 char mq_name[64]; 120 121 #ifdef __FreeBSD__ 122 ATF_REQUIRE_KERNEL_MODULE("mqueuefs"); 123 #endif 124 125 strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template)); 126 tmpdir = mkdtemp(template); 127 ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno); 128 #ifdef __FreeBSD__ 129 snprintf(mq_name, sizeof(mq_name), "/t_mqueue"); 130 #else 131 snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir); 132 #endif 133 134 mqd_t mqfd; 135 136 mqfd = mq_open(mq_name, O_RDWR | O_CREAT, 137 S_IRUSR | S_IRWXG | S_IROTH, NULL); 138 #ifdef __FreeBSD__ 139 ATF_REQUIRE_MSG(mqfd != (mqd_t)-1, "mq_open failed: %d", errno); 140 #else 141 ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno); 142 #endif 143 144 send_msgs(mqfd); 145 receive_msgs(mqfd); 146 147 status = mq_close(mqfd); 148 ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno); 149 } 150 151 ATF_TP_ADD_TCS(tp) 152 { 153 ATF_TP_ADD_TC(tp, mqueue); 154 155 return atf_no_error(); 156 } 157