1272343Sngie/*	$NetBSD: t_mqueue.c,v 1.4 2014/03/02 19:56:48 jmmv Exp $ */
2272343Sngie
3272343Sngie/*
4272343Sngie * Test for POSIX message queue priority handling.
5272343Sngie *
6272343Sngie * This file is in the Public Domain.
7272343Sngie */
8272343Sngie
9272343Sngie#include <atf-c.h>
10272343Sngie
11272343Sngie#include <stdio.h>
12272343Sngie#include <stdlib.h>
13272343Sngie#include <string.h>
14272343Sngie#include <errno.h>
15272343Sngie#include <unistd.h>
16272343Sngie
17272343Sngie#include <mqueue.h>
18272343Sngie
19272343Sngie#define	MQ_PRIO_BASE	24
20272343Sngie
21272343Sngiestatic void
22272343Sngiesend_msgs(mqd_t mqfd)
23272343Sngie{
24272343Sngie	char msg[2];
25272343Sngie
26272343Sngie	msg[1] = '\0';
27272343Sngie
28272343Sngie	msg[0] = 'a';
29272343Sngie	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
30272343Sngie	    "mq_send 1 failed: %d", errno);
31272343Sngie
32272343Sngie	msg[0] = 'b';
33272343Sngie	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
34272343Sngie	    "mq_send 2 failed: %d", errno);
35272343Sngie
36272343Sngie	msg[0] = 'c';
37272343Sngie	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
38272343Sngie	    "mq_send 3 failed: %d", errno);
39272343Sngie
40272343Sngie	msg[0] = 'd';
41272343Sngie	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1,
42272343Sngie	    "mq_send 4 failed: %d", errno);
43272343Sngie
44272343Sngie	msg[0] = 'e';
45272343Sngie	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1,
46272343Sngie	    "mq_send 5 failed: %d", errno);
47272343Sngie
48272343Sngie	msg[0] = 'f';
49272343Sngie	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
50272343Sngie	    "mq_send 6 failed: %d", errno);
51272343Sngie}
52272343Sngie
53272343Sngiestatic void
54272343Sngiereceive_msgs(mqd_t mqfd)
55272343Sngie{
56272343Sngie	struct mq_attr mqa;
57272343Sngie	char *m;
58272343Sngie	unsigned p;
59272343Sngie	int len;
60272343Sngie
61272343Sngie	ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d",
62272343Sngie	    errno);
63272343Sngie
64272343Sngie	len = mqa.mq_msgsize;
65272343Sngie	m = calloc(1, len);
66272343Sngie	ATF_REQUIRE_MSG(m != NULL, "calloc failed");
67272343Sngie
68272343Sngie	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
69272343Sngie	    "mq_receive 1 failed: %d", errno);
70272343Sngie	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b',
71272343Sngie	    "mq_receive 1 prio/data mismatch");
72272343Sngie
73272343Sngie	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
74272343Sngie	    "mq_receive 2 failed: %d", errno);
75272343Sngie	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f',
76272343Sngie	    "mq_receive 2 prio/data mismatch");
77272343Sngie
78272343Sngie	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
79272343Sngie	    "mq_receive 3 failed: %d", errno);
80272343Sngie	ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a',
81272343Sngie	    "mq_receive 3 prio/data mismatch");
82272343Sngie
83272343Sngie	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
84272343Sngie	    "mq_receive 4 failed: %d", errno);
85272343Sngie	ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c',
86272343Sngie	    "mq_receive 4 prio/data mismatch");
87272343Sngie
88272343Sngie	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
89272343Sngie	    "mq_receive 5 failed: %d", errno);
90272343Sngie	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd',
91272343Sngie	    "mq_receive 5 prio/data mismatch");
92272343Sngie
93272343Sngie	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
94272343Sngie	    "mq_receive 6 failed: %d", errno);
95272343Sngie	ATF_REQUIRE_MSG(p == 0 && m[0] == 'e',
96272343Sngie	    "mq_receive 6 prio/data mismatch");
97272343Sngie}
98272343Sngie
99272343SngieATF_TC(mqueue);
100272343SngieATF_TC_HEAD(mqueue, tc)
101272343Sngie{
102272343Sngie
103272343Sngie	atf_tc_set_md_var(tc, "timeout", "3");
104272343Sngie	atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive");
105272343Sngie}
106272343Sngie
107272343SngieATF_TC_BODY(mqueue, tc)
108272343Sngie{
109272343Sngie	int status;
110272343Sngie	char *tmpdir;
111272343Sngie	char template[32];
112272343Sngie	char mq_name[64];
113272343Sngie
114272343Sngie	strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template));
115272343Sngie	tmpdir = mkdtemp(template);
116272343Sngie	ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno);
117272343Sngie	snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir);
118272343Sngie
119272343Sngie	mqd_t mqfd;
120272343Sngie
121272343Sngie	mqfd = mq_open(mq_name, O_RDWR | O_CREAT,
122272343Sngie	    S_IRUSR | S_IRWXG | S_IROTH, NULL);
123272343Sngie	ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno);
124272343Sngie
125272343Sngie	send_msgs(mqfd);
126272343Sngie	receive_msgs(mqfd);
127272343Sngie
128272343Sngie	status = mq_close(mqfd);
129272343Sngie	ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno);
130272343Sngie}
131272343Sngie
132272343SngieATF_TP_ADD_TCS(tp)
133272343Sngie{
134272343Sngie	ATF_TP_ADD_TC(tp, mqueue);
135272343Sngie
136272343Sngie	return atf_no_error();
137272343Sngie}
138