]> git.ipfire.org Git - thirdparty/glibc.git/blob - nptl/tst-cancel4.c
(do_test): Use %zd instead of %d when printing cnt.
[thirdparty/glibc.git] / nptl / tst-cancel4.c
1 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 /* NOTE: this tests functionality beyond POSIX. POSIX does not allow
21 exit to be called more than once. */
22
23 #include <errno.h>
24 #include <limits.h>
25 #include <pthread.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <sys/poll.h>
31 #include <sys/select.h>
32 #include <sys/uio.h>
33 #include <sys/wait.h>
34
35 /* The following interfaces are defined to be cancellation points but
36 tests are not yet implemented:
37
38 accept() aio_suspend() clock_nanosleep()
39 close() connect() creat()
40 fcntl() fsync() getmsg()
41 getpmsg() lockf() mq_receive()
42 mq_send() mq_timedreceive() mq_timedsend()
43 msgrcv() msgsnd() msync()
44 open() pause()
45 pread()
46 pthread_join() pthread_testcancel()
47 putmsg() putpmsg() pwrite()
48 recv()
49 recvfrom() recvmsg()
50 sem_timedwait() sem_wait() send()
51 sendmsg() sendto() sigpause()
52 sigsuspend() sigtimedwait() sigwait()
53 sigwaitinfo()
54 tcdrain()
55
56 Since STREAMS are not supported in the standard Linux kernel there
57 is no need to test the STREAMS related functions.
58 */
59
60 /* Pipe descriptors. */
61 static int fds[2];
62
63 /* Often used barrier for two threads. */
64 static pthread_barrier_t b2;
65
66
67 static void *
68 tf_read (void *arg)
69 {
70 int r = pthread_barrier_wait (&b2);
71 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
72 {
73 printf ("%s: barrier_wait failed\n", __FUNCTION__);
74 exit (1);
75 }
76
77 char buf[100];
78 ssize_t s = read (fds[0], buf, sizeof (buf));
79
80 printf ("%s: read returns with %zd\n", __FUNCTION__, s);
81
82 exit (1);
83 }
84
85
86 static void *
87 tf_readv (void *arg)
88 {
89 int r = pthread_barrier_wait (&b2);
90 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
91 {
92 printf ("%s: barrier_wait failed\n", __FUNCTION__);
93 exit (1);
94 }
95
96 char buf[100];
97 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
98 ssize_t s = readv (fds[0], iov, 1);
99
100 printf ("%s: readv returns with %zd\n", __FUNCTION__, s);
101
102 exit (1);
103 }
104
105
106 static void *
107 tf_write (void *arg)
108 {
109 int r = pthread_barrier_wait (&b2);
110 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
111 {
112 printf ("%s: barrier_wait failed\n", __FUNCTION__);
113 exit (1);
114 }
115
116 char buf[100000];
117 memset (buf, '\0', sizeof (buf));
118 ssize_t s = write (fds[1], buf, sizeof (buf));
119
120 printf ("%s: write returns with %zd\n", __FUNCTION__, s);
121
122 exit (1);
123 }
124
125
126 static void *
127 tf_writev (void *arg)
128 {
129 int r = pthread_barrier_wait (&b2);
130 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
131 {
132 printf ("%s: barrier_wait failed\n", __FUNCTION__);
133 exit (1);
134 }
135
136 char buf[100000];
137 memset (buf, '\0', sizeof (buf));
138 struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
139 ssize_t s = writev (fds[1], iov, 1);
140
141 printf ("%s: writev returns with %zd\n", __FUNCTION__, s);
142
143 exit (1);
144 }
145
146
147 static void *
148 tf_sleep (void *arg)
149 {
150 int r = pthread_barrier_wait (&b2);
151 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
152 {
153 printf ("%s: barrier_wait failed\n", __FUNCTION__);
154 exit (1);
155 }
156
157 sleep (1000000);
158
159 printf ("%s: sleep returns\n", __FUNCTION__);
160
161 exit (1);
162 }
163
164
165 static void *
166 tf_usleep (void *arg)
167 {
168 int r = pthread_barrier_wait (&b2);
169 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
170 {
171 printf ("%s: barrier_wait failed\n", __FUNCTION__);
172 exit (1);
173 }
174
175 usleep ((useconds_t) ULONG_MAX);
176
177 printf ("%s: usleep returns\n", __FUNCTION__);
178
179 exit (1);
180 }
181
182
183 static void *
184 tf_nanosleep (void *arg)
185 {
186 int r = pthread_barrier_wait (&b2);
187 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
188 {
189 printf ("%s: barrier_wait failed\n", __FUNCTION__);
190 exit (1);
191 }
192
193 struct timespec ts = { .tv_sec = 10000000, .tv_nsec = 0 };
194 while (nanosleep (&ts, &ts) != 0)
195 continue;
196
197 printf ("%s: nanosleep returns\n", __FUNCTION__);
198
199 exit (1);
200 }
201
202
203 static void *
204 tf_select (void *arg)
205 {
206 int r = pthread_barrier_wait (&b2);
207 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
208 {
209 printf ("%s: barrier_wait failed\n", __FUNCTION__);
210 exit (1);
211 }
212
213 fd_set rfs;
214 FD_ZERO (&rfs);
215 FD_SET (fds[0], &rfs);
216
217 int s = select (fds[0] + 1, &rfs, NULL, NULL, NULL);
218
219 printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s,
220 strerror (errno));
221
222 exit (1);
223 }
224
225
226 static void *
227 tf_pselect (void *arg)
228 {
229 int r = pthread_barrier_wait (&b2);
230 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
231 {
232 printf ("%s: barrier_wait failed\n", __FUNCTION__);
233 exit (1);
234 }
235
236 fd_set rfs;
237 FD_ZERO (&rfs);
238 FD_SET (fds[0], &rfs);
239
240 int s = pselect (fds[0] + 1, &rfs, NULL, NULL, NULL, NULL);
241
242 printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s,
243 strerror (errno));
244
245 exit (1);
246 }
247
248
249 static void *
250 tf_poll (void *arg)
251 {
252 int r = pthread_barrier_wait (&b2);
253 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
254 {
255 printf ("%s: barrier_wait failed\n", __FUNCTION__);
256 exit (1);
257 }
258
259 struct pollfd rfs[1] = { [0] = { .fd = fds[0], .events = POLLIN } };
260
261 int s = poll (rfs, 1, -1);
262
263 printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s,
264 strerror (errno));
265
266 exit (1);
267 }
268
269
270 static void *
271 tf_wait (void *arg)
272 {
273 int r = pthread_barrier_wait (&b2);
274 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
275 {
276 printf ("%s: barrier_wait failed\n", __FUNCTION__);
277 exit (1);
278 }
279
280 pid_t pid = fork ();
281 if (pid == -1)
282 {
283 puts ("fork failed");
284 exit (1);
285 }
286
287 if (pid == 0)
288 {
289 /* Make the program disappear after a while. */
290 sleep (10);
291 exit (0);
292 }
293
294 int s = wait (NULL);
295
296 printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
297 strerror (errno));
298
299 exit (1);
300 }
301
302
303 static void *
304 tf_waitpid (void *arg)
305 {
306 int r = pthread_barrier_wait (&b2);
307 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
308 {
309 printf ("%s: barrier_wait failed\n", __FUNCTION__);
310 exit (1);
311 }
312
313 pid_t pid = fork ();
314 if (pid == -1)
315 {
316 puts ("fork failed");
317 exit (1);
318 }
319
320 if (pid == 0)
321 {
322 /* Make the program disappear after a while. */
323 sleep (10);
324 exit (0);
325 }
326
327 int s = waitpid (-1, NULL, 0);
328
329 printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
330 strerror (errno));
331
332 exit (1);
333 }
334
335
336 static void *
337 tf_waitid (void *arg)
338 {
339 int r = pthread_barrier_wait (&b2);
340 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
341 {
342 printf ("%s: barrier_wait failed\n", __FUNCTION__);
343 exit (1);
344 }
345
346 pid_t pid = fork ();
347 if (pid == -1)
348 {
349 puts ("fork failed");
350 exit (1);
351 }
352
353 if (pid == 0)
354 {
355 /* Make the program disappear after a while. */
356 sleep (10);
357 exit (0);
358 }
359
360 siginfo_t si;
361 int s = waitid (P_PID, pid, &si, 0);
362
363 printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
364 strerror (errno));
365
366 exit (1);
367 }
368
369
370 static struct
371 {
372 void *(*tf) (void *);
373 int nb;
374 } tests[] =
375 {
376 { tf_read, 2 },
377 { tf_readv, 2 },
378 { tf_select, 2 },
379 { tf_pselect, 2 },
380 { tf_poll, 2 },
381 { tf_write, 2 },
382 { tf_writev, 2},
383 { tf_sleep, 2 },
384 { tf_usleep, 2 },
385 { tf_nanosleep, 2 },
386 { tf_wait, 2 },
387 { tf_waitid, 2 },
388 { tf_waitpid, 2 },
389 };
390 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
391
392
393 static int
394 do_test (void)
395 {
396 if (pipe (fds) != 0)
397 {
398 puts ("pipe failed");
399 exit (1);
400 }
401
402 size_t cnt;
403 for (cnt = 0; cnt < ntest_tf; ++cnt)
404 {
405 if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
406 {
407 puts ("b2 init failed");
408 exit (1);
409 }
410
411 /* read(2) test. */
412 pthread_t th;
413 if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
414 {
415 printf ("create for round %zd test failed\n", cnt);
416 exit (1);
417 }
418
419 int r = pthread_barrier_wait (&b2);
420 if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
421 {
422 printf ("%s: barrier_wait failed\n", __FUNCTION__);
423 exit (1);
424 }
425
426 struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
427 while (nanosleep (&ts, &ts) != 0)
428 continue;
429
430 if (pthread_cancel (th) != 0)
431 {
432 printf ("cancel in round %zd failed\n", cnt);
433 exit (1);
434 }
435
436 void *status;
437 if (pthread_join (th, &status) != 0)
438 {
439 printf ("join in round %zd failed\n", cnt);
440 exit (1);
441 }
442 if (status != PTHREAD_CANCELED)
443 {
444 printf ("thread in round %zd not canceled\n", cnt);
445 exit (1);
446 }
447 printf ("test %zd successful\n", cnt);
448
449 if (pthread_barrier_destroy (&b2) != 0)
450 {
451 puts ("barrier_destroy failed");
452 exit (1);
453 }
454 }
455
456 return 0;
457 }
458
459 #define TIMEOUT 60
460 #define TEST_FUNCTION do_test ()
461 #include "../test-skeleton.c"