]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/test/nptl/tst-mqueue6.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / test / nptl / tst-mqueue6.c
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, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <mqueue.h>
23 #include <limits.h>
24 #include <signal.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/mman.h>
30 #include <sys/time.h>
31 #include <sys/wait.h>
32 #include <time.h>
33 #include <unistd.h>
34 #include "tst-mqueue.h"
35
36 #if _POSIX_THREADS
37 # include <pthread.h>
38
39 # define mqsend(q) (mqsend) (q, __LINE__)
40 static int
41 (mqsend) (mqd_t q, int line)
42 {
43   char c;
44   if (mq_send (q, &c, 1, 1) != 0)
45     {
46       printf ("mq_send on line %d failed with: %m\n", line);
47       return 1;
48     }
49   return 0;
50 }
51
52 # define mqrecv(q) (mqrecv) (q, __LINE__)
53 static int
54 (mqrecv) (mqd_t q, int line)
55 {
56   char c;
57   ssize_t rets = TEMP_FAILURE_RETRY (mq_receive (q, &c, 1, NULL));
58   if (rets != 1)
59     {
60       if (rets == -1)
61         printf ("mq_receive on line %d failed with: %m\n", line);
62       else
63         printf ("mq_receive on line %d returned %zd != 1\n",
64                 line, rets);
65       return 1;
66     }
67   return 0;
68 }
69
70 volatile int fct_cnt, fct_err;
71 size_t fct_guardsize;
72
73 static void
74 fct (union sigval s)
75 {
76   mqd_t q = *(mqd_t *) s.sival_ptr;
77
78   pthread_attr_t nattr;
79   int ret = pthread_getattr_np (pthread_self (), &nattr);
80   if (ret)
81     {
82       errno = ret;
83       printf ("pthread_getattr_np failed: %m\n");
84       fct_err = 1;
85     }
86   else
87     {
88       ret = pthread_attr_getguardsize (&nattr, &fct_guardsize);
89       if (ret)
90         {
91           errno = ret;
92           printf ("pthread_attr_getguardsize failed: %m\n");
93           fct_err = 1;
94         }
95       if (pthread_attr_destroy (&nattr) != 0)
96         {
97           puts ("pthread_attr_destroy failed");
98           fct_err = 1;
99         }
100     }
101
102   ++fct_cnt;
103   fct_err |= mqsend (q);
104 }
105
106 # define TEST_FUNCTION do_test ()
107 static int
108 do_test (void)
109 {
110   int result = 0;
111
112   char name[sizeof "/tst-mqueue6-" + sizeof (pid_t) * 3];
113   snprintf (name, sizeof (name), "/tst-mqueue6-%u", getpid ());
114
115   struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 };
116   mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
117
118   if (q == (mqd_t) -1)
119     {
120       printf ("mq_open failed with: %m\n");
121       return result;
122     }
123   else
124     add_temp_mq (name);
125
126   pthread_attr_t nattr;
127   if (pthread_attr_init (&nattr)
128       || pthread_attr_setguardsize (&nattr, 0))
129     {
130       puts ("pthread_attr_t setup failed");
131       result = 1;
132     }
133
134   fct_guardsize = 1;
135
136   struct sigevent ev;
137   memset (&ev, 0xaa, sizeof (ev));
138   ev.sigev_notify = SIGEV_THREAD;
139   ev.sigev_notify_function = fct;
140   ev.sigev_notify_attributes = &nattr;
141   ev.sigev_value.sival_ptr = &q;
142   if (mq_notify (q, &ev) != 0)
143     {
144       printf ("mq_notify (q, { SIGEV_THREAD }) failed with: %m\n");
145       result = 1;
146     }
147
148   size_t ps = sysconf (_SC_PAGESIZE);
149   if (pthread_attr_setguardsize (&nattr, 32 * ps))
150     {
151       puts ("pthread_attr_t setup failed");
152       result = 1;
153     }
154
155   if (mq_notify (q, &ev) == 0)
156     {
157       puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
158       result = 1;
159     }
160   else if (errno != EBUSY)
161     {
162       printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
163       result = 1;
164     }
165
166   if (fct_cnt != 0)
167     {
168       printf ("fct called too early (%d on %d)\n", fct_cnt, __LINE__);
169       result = 1;
170     }
171
172   result |= mqsend (q);
173
174   result |= mqrecv (q);
175   result |= mqrecv (q);
176
177   if (fct_cnt != 1)
178     {
179       printf ("fct not called (%d on %d)\n", fct_cnt, __LINE__);
180       result = 1;
181     }
182   else if (fct_guardsize != 0)
183     {
184       printf ("fct_guardsize %zd != 0\n", fct_guardsize);
185       result = 1;
186     }
187
188   if (mq_notify (q, &ev) != 0)
189     {
190       printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
191       result = 1;
192     }
193
194   if (mq_notify (q, NULL) != 0)
195     {
196       printf ("mq_notify (q, NULL) failed with: %m\n");
197       result = 1;
198     }
199
200   memset (&ev, 0x11, sizeof (ev));
201   ev.sigev_notify = SIGEV_THREAD;
202   ev.sigev_notify_function = fct;
203   ev.sigev_notify_attributes = &nattr;
204   ev.sigev_value.sival_ptr = &q;
205   if (mq_notify (q, &ev) != 0)
206     {
207       printf ("mq_notify (q, { SIGEV_THREAD }) failed with: %m\n");
208       result = 1;
209     }
210
211   if (pthread_attr_setguardsize (&nattr, 0))
212     {
213       puts ("pthread_attr_t setup failed");
214       result = 1;
215     }
216
217   if (mq_notify (q, &ev) == 0)
218     {
219       puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
220       result = 1;
221     }
222   else if (errno != EBUSY)
223     {
224       printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
225       result = 1;
226     }
227
228   if (fct_cnt != 1)
229     {
230       printf ("fct called too early (%d on %d)\n", fct_cnt, __LINE__);
231       result = 1;
232     }
233
234   result |= mqsend (q);
235
236   result |= mqrecv (q);
237   result |= mqrecv (q);
238
239   if (fct_cnt != 2)
240     {
241       printf ("fct not called (%d on %d)\n", fct_cnt, __LINE__);
242       result = 1;
243     }
244   else if (fct_guardsize != 32 * ps)
245     {
246       printf ("fct_guardsize %zd != %zd\n", fct_guardsize, 32 * ps);
247       result = 1;
248     }
249
250   if (mq_notify (q, &ev) != 0)
251     {
252       printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
253       result = 1;
254     }
255
256   if (mq_notify (q, NULL) != 0)
257     {
258       printf ("mq_notify (q, NULL) failed with: %m\n");
259       result = 1;
260     }
261
262   if (pthread_attr_destroy (&nattr) != 0)
263     {
264       puts ("pthread_attr_destroy failed");
265       result = 1;
266     }
267
268   if (mq_unlink (name) != 0)
269     {
270       printf ("mq_unlink failed: %m\n");
271       result = 1;
272     }
273
274   if (mq_close (q) != 0)
275     {
276       printf ("mq_close failed: %m\n");
277       result = 1;
278     }
279
280   memset (&ev, 0x55, sizeof (ev));
281   ev.sigev_notify = SIGEV_THREAD;
282   ev.sigev_notify_function = fct;
283   ev.sigev_notify_attributes = NULL;
284   ev.sigev_value.sival_int = 0;
285   if (mq_notify (q, &ev) == 0)
286     {
287       puts ("mq_notify on closed mqd_t unexpectedly succeeded");
288       result = 1;
289     }
290   else if (errno != EBADF)
291     {
292       printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n");
293       result = 1;
294     }
295
296   if (fct_err)
297     result = 1;
298   return result;
299 }
300 #else
301 # define TEST_FUNCTION 0
302 #endif
303
304 #include "../test-skeleton.c"