• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Crackerjack Project., 2007-2008, Hitachi, Ltd
3  * Copyright (c) 2017 Petr Vorel <pvorel@suse.cz>
4  *
5  * Authors:
6  * Takahiro Yasui <takahiro.yasui.mp@hitachi.com>,
7  * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>,
8  * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it would be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #include <errno.h>
25 #include <limits.h>
26 
27 static int fd, fd_root, fd_nonblock, fd_maxint = INT_MAX - 1, fd_invalid = -1;
28 
29 #include "mq_timed.h"
30 
31 static struct timespec ts;
32 
33 static struct test_case tcase[] = {
34 	{
35 		.fd = &fd,
36 		.len = 0,
37 		.send = 1,
38 		.ret = 0,
39 		.err = 0,
40 	},
41 	{
42 		.fd = &fd,
43 		.len = 1,
44 		.send = 1,
45 		.ret = 0,
46 		.err = 0,
47 	},
48 	{
49 		.fd = &fd,
50 		.len = MAX_MSGSIZE,
51 		.send = 1,
52 		.ret = 0,
53 		.err = 0,
54 	},
55 	{
56 		.fd = &fd,
57 		.len = 1,
58 		.send = 1,
59 		.prio = MQ_PRIO_MAX - 1,
60 		.ret = 0,
61 		.err = 0,
62 	},
63 	{
64 		.fd = &fd,
65 		.invalid_msg = 1,
66 		.len = 0,
67 		.send = 1,
68 		.ret = -1,
69 		.err = EMSGSIZE,
70 	},
71 	{
72 		.fd = &fd_invalid,
73 		.len = 0,
74 		.ret = -1,
75 		.err = EBADF,
76 	},
77 	{
78 		.fd = &fd_maxint,
79 		.len = 0,
80 		.ret = -1,
81 		.err = EBADF,
82 	},
83 	{
84 		.fd = &fd_root,
85 		.len = 0,
86 		.ret = -1,
87 		.err = EBADF,
88 	},
89 	{
90 		.fd = &fd_nonblock,
91 		.len = 16,
92 		.ret = -1,
93 		.err = EAGAIN,
94 	},
95 	{
96 		.fd = &fd,
97 		.len = 16,
98 		.rq = &(struct timespec) {.tv_sec = -1, .tv_nsec = 0},
99 		.ret = -1,
100 		.err = EINVAL,
101 	},
102 	{
103 		.fd = &fd,
104 		.len = 16,
105 		.rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = -1},
106 		.ret = -1,
107 		.err = EINVAL,
108 	},
109 	{
110 		.fd = &fd,
111 		.len = 16,
112 		.rq = &(struct timespec) {.tv_sec = 0, .tv_nsec = 1000000000},
113 		.ret = -1,
114 		.err = EINVAL,
115 	},
116 	{
117 		.fd = &fd,
118 		.len = 16,
119 		.timeout = 1,
120 		.ret = -1,
121 		.rq = &ts,
122 		.err = ETIMEDOUT,
123 	},
124 	{
125 		.fd = &fd,
126 		.len = 16,
127 		.signal = 1,
128 		.rq = &ts,
129 		.ret = -1,
130 		.err = EINTR,
131 	},
132 };
133 
do_test(unsigned int i)134 static void do_test(unsigned int i)
135 {
136 	const struct test_case *tc = &tcase[i];
137 	unsigned int j;
138 	unsigned int prio;
139 	size_t len = MAX_MSGSIZE;
140 	char rmsg[len];
141 	pid_t pid = -1;
142 
143 	if (tc->signal)
144 		pid = set_sig(tc->rq);
145 
146 	if (tc->timeout)
147 		set_timeout(tc->rq);
148 
149 	if (tc->send)
150 		send_msg(*tc->fd, tc->len, tc->prio);
151 
152 	if (tc->invalid_msg)
153 		len -= 1;
154 
155 	TEST(mq_timedreceive(*tc->fd, rmsg, len, &prio, tc->rq));
156 
157 	if (pid > 0)
158 		kill_pid(pid);
159 
160 	if (*tc->fd == fd)
161 		cleanup_queue(fd);
162 
163 	if (TST_RET < 0) {
164 		if (tc->err != TST_ERR)
165 			tst_res(TFAIL | TTERRNO,
166 				"mq_timedreceive failed unexpectedly, expected %s",
167 				tst_strerrno(tc->err));
168 		else
169 			tst_res(TPASS | TTERRNO, "mq_timedreceive failed expectedly");
170 
171 		return;
172 	}
173 
174 	if (tc->len != TST_RET) {
175 		tst_res(TFAIL, "mq_timedreceive wrong length %ld, expected %zu",
176 			TST_RET, tc->len);
177 		return;
178 	}
179 
180 	if (tc->prio != prio) {
181 		tst_res(TFAIL, "mq_timedreceive wrong prio %d, expected %d",
182 			prio, tc->prio);
183 		return;
184 	}
185 
186 	for (j = 0; j < tc->len; j++) {
187 		if (rmsg[j] != smsg[j]) {
188 			tst_res(TFAIL,
189 				"mq_timedreceive wrong data %d in %u, expected %d",
190 				rmsg[j], i, smsg[j]);
191 			return;
192 		}
193 	}
194 
195 	tst_res(TPASS, "mq_timedreceive returned %ld, priority %u, length: %zu",
196 			TST_RET, prio, len);
197 }
198 
199 static struct tst_test test = {
200 	.tcnt = ARRAY_SIZE(tcase),
201 	.test = do_test,
202 	.setup = setup_common,
203 	.cleanup = cleanup_common,
204 	.forks_child = 1,
205 };
206