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