summaryrefslogtreecommitdiffstats
path: root/contrib/netbsd-tests/kernel/t_mqueue.c
blob: 485269fa993779ca7d43507a4d50667653649afb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*	$NetBSD: t_mqueue.c,v 1.5 2017/01/10 22:10:22 christos Exp $ */

/*
 * Test for POSIX message queue priority handling.
 *
 * This file is in the Public Domain.
 */

#ifdef __FreeBSD__
#include <sys/stat.h>
#include <fcntl.h>

#include "freebsd_test_suite/macros.h"
#endif

#include <atf-c.h>
#include <sys/stat.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <mqueue.h>

#define	MQ_PRIO_BASE	24

static void
send_msgs(mqd_t mqfd)
{
	char msg[2];

	msg[1] = '\0';

	msg[0] = 'a';
	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
	    "mq_send 1 failed: %d", errno);

	msg[0] = 'b';
	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
	    "mq_send 2 failed: %d", errno);

	msg[0] = 'c';
	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
	    "mq_send 3 failed: %d", errno);

	msg[0] = 'd';
	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1,
	    "mq_send 4 failed: %d", errno);

	msg[0] = 'e';
	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1,
	    "mq_send 5 failed: %d", errno);

	msg[0] = 'f';
	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
	    "mq_send 6 failed: %d", errno);
}

static void
receive_msgs(mqd_t mqfd)
{
	struct mq_attr mqa;
	char *m;
	unsigned p;
	int len;

	ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d",
	    errno);

	len = mqa.mq_msgsize;
	m = calloc(1, len);
	ATF_REQUIRE_MSG(m != NULL, "calloc failed");

	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
	    "mq_receive 1 failed: %d", errno);
	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b',
	    "mq_receive 1 prio/data mismatch");

	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
	    "mq_receive 2 failed: %d", errno);
	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f',
	    "mq_receive 2 prio/data mismatch");

	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
	    "mq_receive 3 failed: %d", errno);
	ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a',
	    "mq_receive 3 prio/data mismatch");

	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
	    "mq_receive 4 failed: %d", errno);
	ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c',
	    "mq_receive 4 prio/data mismatch");

	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
	    "mq_receive 5 failed: %d", errno);
	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd',
	    "mq_receive 5 prio/data mismatch");

	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
	    "mq_receive 6 failed: %d", errno);
	ATF_REQUIRE_MSG(p == 0 && m[0] == 'e',
	    "mq_receive 6 prio/data mismatch");
}

ATF_TC(mqueue);
ATF_TC_HEAD(mqueue, tc)
{

	atf_tc_set_md_var(tc, "timeout", "3");
	atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive");
}

ATF_TC_BODY(mqueue, tc)
{
	int status;
	char *tmpdir;
	char template[32];
	char mq_name[64];

#ifdef __FreeBSD__
	ATF_REQUIRE_KERNEL_MODULE("mqueuefs");
#endif

	strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template));
	tmpdir = mkdtemp(template);
	ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno);
#ifdef __FreeBSD__
	snprintf(mq_name, sizeof(mq_name), "/t_mqueue");
#else
	snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir);
#endif

	mqd_t mqfd;

	mqfd = mq_open(mq_name, O_RDWR | O_CREAT,
	    S_IRUSR | S_IRWXG | S_IROTH, NULL);
#ifdef __FreeBSD__
	ATF_REQUIRE_MSG(mqfd != (mqd_t)-1, "mq_open failed: %d", errno);
#else
	ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno);
#endif

	send_msgs(mqfd);
	receive_msgs(mqfd);

	status = mq_close(mqfd);
	ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno);
}

ATF_TP_ADD_TCS(tp)
{
	ATF_TP_ADD_TC(tp, mqueue); 

	return atf_no_error();
}
OpenPOWER on IntegriCloud