source: branches/libc-0.6/src/libctests/glibc/rt/tst-mqueue6.c

Last change on this file was 2036, checked in by bird, 20 years ago

Initial revision

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