]> git.ipfire.org Git - thirdparty/glibc.git/blame - rt/tst-mqueue6.c
Remove "Contributed by" lines
[thirdparty/glibc.git] / rt / tst-mqueue6.c
CommitLineData
efa8adf5 1/* Test mq_notify.
2b778ceb 2 Copyright (C) 2004-2021 Free Software Foundation, Inc.
efa8adf5 3 This file is part of the GNU C Library.
efa8adf5
UD
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
efa8adf5
UD
18
19#include <errno.h>
20#include <fcntl.h>
21#include <mqueue.h>
22#include <limits.h>
23#include <signal.h>
24#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <sys/mman.h>
29#include <sys/time.h>
30#include <sys/wait.h>
31#include <time.h>
32#include <unistd.h>
33#include "tst-mqueue.h"
34
35#if _POSIX_THREADS
36# include <pthread.h>
37
5adac0e4
UD
38# define mqsend(q) (mqsend) (q, __LINE__)
39static int
efa8adf5
UD
40(mqsend) (mqd_t q, int line)
41{
42 char c;
43 if (mq_send (q, &c, 1, 1) != 0)
44 {
45 printf ("mq_send on line %d failed with: %m\n", line);
46 return 1;
47 }
48 return 0;
49}
50
5adac0e4
UD
51# define mqrecv(q) (mqrecv) (q, __LINE__)
52static int
efa8adf5
UD
53(mqrecv) (mqd_t q, int line)
54{
55 char c;
56 ssize_t rets = TEMP_FAILURE_RETRY (mq_receive (q, &c, 1, NULL));
57 if (rets != 1)
58 {
59 if (rets == -1)
60 printf ("mq_receive on line %d failed with: %m\n", line);
61 else
62 printf ("mq_receive on line %d returned %zd != 1\n",
63 line, rets);
64 return 1;
65 }
66 return 0;
67}
68
69volatile int fct_cnt, fct_err;
70size_t fct_guardsize;
71
72static void
73fct (union sigval s)
74{
75 mqd_t q = *(mqd_t *) s.sival_ptr;
76
77 pthread_attr_t nattr;
78 int ret = pthread_getattr_np (pthread_self (), &nattr);
79 if (ret)
80 {
81 errno = ret;
82 printf ("pthread_getattr_np failed: %m\n");
83 fct_err = 1;
84 }
85 else
86 {
87 ret = pthread_attr_getguardsize (&nattr, &fct_guardsize);
88 if (ret)
89 {
90 errno = ret;
91 printf ("pthread_attr_getguardsize failed: %m\n");
92 fct_err = 1;
93 }
94 if (pthread_attr_destroy (&nattr) != 0)
95 {
96 puts ("pthread_attr_destroy failed");
97 fct_err = 1;
98 }
99 }
100
101 ++fct_cnt;
102 fct_err |= mqsend (q);
103}
104
5adac0e4 105# define TEST_FUNCTION do_test ()
efa8adf5
UD
106static int
107do_test (void)
108{
109 int result = 0;
110
111 char name[sizeof "/tst-mqueue6-" + sizeof (pid_t) * 3];
112 snprintf (name, sizeof (name), "/tst-mqueue6-%u", getpid ());
113
114 struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 };
115 mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
116
117 if (q == (mqd_t) -1)
118 {
119 printf ("mq_open failed with: %m\n");
120 return result;
121 }
122 else
123 add_temp_mq (name);
124
125 pthread_attr_t nattr;
126 if (pthread_attr_init (&nattr)
127 || pthread_attr_setguardsize (&nattr, 0))
128 {
129 puts ("pthread_attr_t setup failed");
130 result = 1;
131 }
132
133 fct_guardsize = 1;
134
135 struct sigevent ev;
136 memset (&ev, 0xaa, sizeof (ev));
137 ev.sigev_notify = SIGEV_THREAD;
138 ev.sigev_notify_function = fct;
139 ev.sigev_notify_attributes = &nattr;
140 ev.sigev_value.sival_ptr = &q;
141 if (mq_notify (q, &ev) != 0)
142 {
143 printf ("mq_notify (q, { SIGEV_THREAD }) failed with: %m\n");
144 result = 1;
145 }
146
147 size_t ps = sysconf (_SC_PAGESIZE);
148 if (pthread_attr_setguardsize (&nattr, 32 * ps))
149 {
150 puts ("pthread_attr_t setup failed");
151 result = 1;
152 }
153
154 if (mq_notify (q, &ev) == 0)
155 {
156 puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
157 result = 1;
158 }
159 else if (errno != EBUSY)
160 {
161 printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
162 result = 1;
163 }
164
165 if (fct_cnt != 0)
166 {
167 printf ("fct called too early (%d on %d)\n", fct_cnt, __LINE__);
168 result = 1;
169 }
170
171 result |= mqsend (q);
172
173 result |= mqrecv (q);
174 result |= mqrecv (q);
175
176 if (fct_cnt != 1)
177 {
178 printf ("fct not called (%d on %d)\n", fct_cnt, __LINE__);
179 result = 1;
180 }
181 else if (fct_guardsize != 0)
182 {
183 printf ("fct_guardsize %zd != 0\n", fct_guardsize);
184 result = 1;
185 }
186
187 if (mq_notify (q, &ev) != 0)
188 {
189 printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
190 result = 1;
191 }
192
193 if (mq_notify (q, NULL) != 0)
194 {
195 printf ("mq_notify (q, NULL) failed with: %m\n");
196 result = 1;
197 }
198
199 memset (&ev, 0x11, sizeof (ev));
200 ev.sigev_notify = SIGEV_THREAD;
201 ev.sigev_notify_function = fct;
202 ev.sigev_notify_attributes = &nattr;
203 ev.sigev_value.sival_ptr = &q;
204 if (mq_notify (q, &ev) != 0)
205 {
206 printf ("mq_notify (q, { SIGEV_THREAD }) failed with: %m\n");
207 result = 1;
208 }
209
210 if (pthread_attr_setguardsize (&nattr, 0))
211 {
212 puts ("pthread_attr_t setup failed");
213 result = 1;
214 }
215
216 if (mq_notify (q, &ev) == 0)
217 {
218 puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
219 result = 1;
220 }
221 else if (errno != EBUSY)
222 {
223 printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
224 result = 1;
225 }
226
227 if (fct_cnt != 1)
228 {
229 printf ("fct called too early (%d on %d)\n", fct_cnt, __LINE__);
230 result = 1;
231 }
232
233 result |= mqsend (q);
234
235 result |= mqrecv (q);
236 result |= mqrecv (q);
237
238 if (fct_cnt != 2)
239 {
240 printf ("fct not called (%d on %d)\n", fct_cnt, __LINE__);
241 result = 1;
242 }
243 else if (fct_guardsize != 32 * ps)
244 {
245 printf ("fct_guardsize %zd != %zd\n", fct_guardsize, 32 * ps);
246 result = 1;
247 }
248
249 if (mq_notify (q, &ev) != 0)
250 {
251 printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
252 result = 1;
253 }
254
255 if (mq_notify (q, NULL) != 0)
256 {
257 printf ("mq_notify (q, NULL) failed with: %m\n");
258 result = 1;
259 }
260
261 if (pthread_attr_destroy (&nattr) != 0)
262 {
263 puts ("pthread_attr_destroy failed");
264 result = 1;
265 }
266
267 if (mq_unlink (name) != 0)
268 {
269 printf ("mq_unlink failed: %m\n");
270 result = 1;
271 }
272
273 if (mq_close (q) != 0)
274 {
275 printf ("mq_close failed: %m\n");
276 result = 1;
277 }
278
279 memset (&ev, 0x55, sizeof (ev));
280 ev.sigev_notify = SIGEV_THREAD;
281 ev.sigev_notify_function = fct;
282 ev.sigev_notify_attributes = NULL;
283 ev.sigev_value.sival_int = 0;
284 if (mq_notify (q, &ev) == 0)
285 {
286 puts ("mq_notify on closed mqd_t unexpectedly succeeded");
287 result = 1;
288 }
289 else if (errno != EBADF)
290 {
291 printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n");
292 result = 1;
293 }
294
295 if (fct_err)
296 result = 1;
297 return result;
298}
299#else
300# define TEST_FUNCTION 0
301#endif
302
303#include "../test-skeleton.c"