OSDN Git Service

test: NPTL: sync WRITE_BUFFER_SIZE with glibc test
[uclinux-h8/uClibc.git] / test / nptl / tst-cancel4.c
1 /* Copyright (C) 2002, 2003, 2004, 2006, 2007 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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 /* NOTE: this tests functionality beyond POSIX.  POSIX does not allow
20    exit to be called more than once.  */
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <limits.h>
25 #include <pthread.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <termios.h>
31 #include <unistd.h>
32 #include <sys/mman.h>
33 #include <sys/msg.h>
34 #include <sys/poll.h>
35 #include <sys/select.h>
36 #include <sys/socket.h>
37 #include <sys/uio.h>
38 #include <sys/un.h>
39 #include <sys/wait.h>
40
41 #include "pthreadP.h"
42
43
44 /* Since STREAMS are not supported in the standard Linux kernel and
45    there we don't advertise STREAMS as supported is no need to test
46    the STREAMS related functions.  This affects
47      getmsg()              getpmsg()          putmsg()
48      putpmsg()
49
50    lockf() and fcntl() are tested in tst-cancel16.
51
52    pthread_join() is tested in tst-join5.
53
54    pthread_testcancel()'s only purpose is to allow cancellation.  This
55    is tested in several places.
56
57    sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests.
58
59    mq_send(), mq_timedsend(), mq_receive() and mq_timedreceive() are checked
60    in tst-mqueue8{,x} tests.
61
62    aio_suspend() is tested in tst-cancel17.
63
64    clock_nanosleep() is tested in tst-cancel18.
65 */
66
67 /* Pipe descriptors.  */
68 static int fds[2];
69
70 /* Temporary file descriptor, to be closed after each round.  */
71 static int tempfd = -1;
72 static int tempfd2 = -1;
73 /* Name of temporary file to be removed after each round.  */
74 static char *tempfname;
75 /* Temporary message queue.  */
76 static int tempmsg = -1;
77
78 /* Often used barrier for two threads.  */
79 static pthread_barrier_t b2;
80
81
82 #ifndef IPC_ADDVAL
83 # define IPC_ADDVAL 0
84 #endif
85
86 /* The WRITE_BUFFER_SIZE value needs to be chosen such that if we set
87    the socket send buffer size to '1', a write of this size on that
88    socket will block.
89
90    The Linux kernel imposes a minimum send socket buffer size which
91    has changed over the years.  As of Linux 3.10 the value is:
92
93      2 * (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff)))
94
95    which is attempting to make sure that with standard MTUs,
96    TCP can always queue up at least 2 full sized packets.
97
98    Furthermore, there is logic in the socket send paths that
99    will allow one more packet (of any size) to be queued up as
100    long as some socket buffer space remains.   Blocking only
101    occurs when we try to queue up a new packet and the send
102    buffer space has already been fully consumed.
103
104    Therefore we must set this value to the largest possible value of
105    the formula above (and since it depends upon the size of "struct
106    sk_buff", it is dependent upon machine word size etc.) plus some
107    slack space.  */
108
109 #define WRITE_BUFFER_SIZE 16384
110
111 /* Cleanup handling test.  */
112 static int cl_called;
113
114 static void
115 cl (void *arg)
116 {
117   ++cl_called;
118 }
119
120
121
122 static void *
123 tf_read  (void *arg)
124 {
125   int fd;
126   int r;
127
128   if (arg == NULL)
129     fd = fds[0];
130   else
131     {
132       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
133       tempfd = fd = mkstemp (fname);
134       if (fd == -1)
135         printf ("%s: mkstemp failed\n", __FUNCTION__);
136       unlink (fname);
137
138       r = pthread_barrier_wait (&b2);
139       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
140         {
141           printf ("%s: barrier_wait failed\n", __FUNCTION__);
142           exit (1);
143         }
144     }
145
146   r = pthread_barrier_wait (&b2);
147   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
148     {
149       printf ("%s: barrier_wait failed\n", __FUNCTION__);
150       exit (1);
151     }
152
153   ssize_t s;
154   pthread_cleanup_push (cl, NULL);
155
156   char buf[100];
157   s = read (fd, buf, sizeof (buf));
158
159   pthread_cleanup_pop (0);
160
161   printf ("%s: read returns with %zd\n", __FUNCTION__, s);
162
163   exit (1);
164 }
165
166
167 static void *
168 tf_readv  (void *arg)
169 {
170   int fd;
171   int r;
172
173   if (arg == NULL)
174     fd = fds[0];
175   else
176     {
177       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
178       tempfd = fd = mkstemp (fname);
179       if (fd == -1)
180         printf ("%s: mkstemp failed\n", __FUNCTION__);
181       unlink (fname);
182
183       r = pthread_barrier_wait (&b2);
184       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
185         {
186           printf ("%s: barrier_wait failed\n", __FUNCTION__);
187           exit (1);
188         }
189     }
190
191   r = pthread_barrier_wait (&b2);
192   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
193     {
194       printf ("%s: barrier_wait failed\n", __FUNCTION__);
195       exit (1);
196     }
197
198   ssize_t s;
199   pthread_cleanup_push (cl, NULL);
200
201   char buf[100];
202   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
203   s = readv (fd, iov, 1);
204
205   pthread_cleanup_pop (0);
206
207   printf ("%s: readv returns with %zd\n", __FUNCTION__, s);
208
209   exit (1);
210 }
211
212
213 static void *
214 tf_write  (void *arg)
215 {
216   int fd;
217   int r;
218
219   if (arg == NULL)
220     fd = fds[1];
221   else
222     {
223       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
224       tempfd = fd = mkstemp (fname);
225       if (fd == -1)
226         printf ("%s: mkstemp failed\n", __FUNCTION__);
227       unlink (fname);
228
229       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
237   r = pthread_barrier_wait (&b2);
238   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
239     {
240       printf ("%s: barrier_wait failed\n", __FUNCTION__);
241       exit (1);
242     }
243
244   ssize_t s;
245   pthread_cleanup_push (cl, NULL);
246
247   char buf[WRITE_BUFFER_SIZE];
248   memset (buf, '\0', sizeof (buf));
249   s = write (fd, buf, sizeof (buf));
250
251   pthread_cleanup_pop (0);
252
253   printf ("%s: write returns with %zd\n", __FUNCTION__, s);
254
255   exit (1);
256 }
257
258
259 static void *
260 tf_writev  (void *arg)
261 {
262   int fd;
263   int r;
264
265   if (arg == NULL)
266     fd = fds[1];
267   else
268     {
269       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
270       tempfd = fd = mkstemp (fname);
271       if (fd == -1)
272         printf ("%s: mkstemp failed\n", __FUNCTION__);
273       unlink (fname);
274
275       r = pthread_barrier_wait (&b2);
276       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
277         {
278           printf ("%s: barrier_wait failed\n", __FUNCTION__);
279           exit (1);
280         }
281     }
282
283   r = pthread_barrier_wait (&b2);
284   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
285     {
286       printf ("%s: barrier_wait failed\n", __FUNCTION__);
287       exit (1);
288     }
289
290   ssize_t s;
291   pthread_cleanup_push (cl, NULL);
292
293   char buf[WRITE_BUFFER_SIZE];
294   memset (buf, '\0', sizeof (buf));
295   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
296   s = writev (fd, iov, 1);
297
298   pthread_cleanup_pop (0);
299
300   printf ("%s: writev returns with %zd\n", __FUNCTION__, s);
301
302   exit (1);
303 }
304
305
306 static void *
307 tf_sleep (void *arg)
308 {
309   int r = pthread_barrier_wait (&b2);
310   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
311     {
312       printf ("%s: barrier_wait failed\n", __FUNCTION__);
313       exit (1);
314     }
315
316   if (arg != NULL)
317     {
318       r = pthread_barrier_wait (&b2);
319       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
320         {
321           printf ("%s: barrier_wait failed\n", __FUNCTION__);
322           exit (1);
323         }
324     }
325
326   pthread_cleanup_push (cl, NULL);
327
328   sleep (arg == NULL ? 1000000 : 0);
329
330   pthread_cleanup_pop (0);
331
332   printf ("%s: sleep returns\n", __FUNCTION__);
333
334   exit (1);
335 }
336
337
338 static void *
339 tf_usleep (void *arg)
340 {
341   int r = pthread_barrier_wait (&b2);
342   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
343     {
344       printf ("%s: barrier_wait failed\n", __FUNCTION__);
345       exit (1);
346     }
347
348   if (arg != NULL)
349     {
350       r = pthread_barrier_wait (&b2);
351       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
352         {
353           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
354           exit (1);
355         }
356     }
357
358   pthread_cleanup_push (cl, NULL);
359
360   usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0);
361
362   pthread_cleanup_pop (0);
363
364   printf ("%s: usleep returns\n", __FUNCTION__);
365
366   exit (1);
367 }
368
369
370 static void *
371 tf_nanosleep (void *arg)
372 {
373   int r = pthread_barrier_wait (&b2);
374   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
375     {
376       printf ("%s: barrier_wait failed\n", __FUNCTION__);
377       exit (1);
378     }
379
380   if (arg != NULL)
381     {
382       r = pthread_barrier_wait (&b2);
383       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
384         {
385           printf ("%s: barrier_wait failed\n", __FUNCTION__);
386           exit (1);
387         }
388     }
389
390   pthread_cleanup_push (cl, NULL);
391
392   struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 };
393   TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
394
395   pthread_cleanup_pop (0);
396
397   printf ("%s: nanosleep returns\n", __FUNCTION__);
398
399   exit (1);
400 }
401
402
403 static void *
404 tf_select (void *arg)
405 {
406   int fd;
407   int r;
408
409   if (arg == NULL)
410     fd = fds[0];
411   else
412     {
413       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
414       tempfd = fd = mkstemp (fname);
415       if (fd == -1)
416         printf ("%s: mkstemp failed\n", __FUNCTION__);
417       unlink (fname);
418
419       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
427   r = pthread_barrier_wait (&b2);
428   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
429     {
430       printf ("%s: barrier_wait failed\n", __FUNCTION__);
431       exit (1);
432     }
433
434   fd_set rfs;
435   FD_ZERO (&rfs);
436   FD_SET (fd, &rfs);
437
438   int s;
439   pthread_cleanup_push (cl, NULL);
440
441   s = select (fd + 1, &rfs, NULL, NULL, NULL);
442
443   pthread_cleanup_pop (0);
444
445   printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s,
446           strerror (errno));
447
448   exit (1);
449 }
450
451
452 static void *
453 tf_pselect (void *arg)
454 {
455   int fd;
456   int r;
457
458   if (arg == NULL)
459     fd = fds[0];
460   else
461     {
462       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
463       tempfd = fd = mkstemp (fname);
464       if (fd == -1)
465         printf ("%s: mkstemp failed\n", __FUNCTION__);
466       unlink (fname);
467
468       r = pthread_barrier_wait (&b2);
469       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
470         {
471           printf ("%s: barrier_wait failed\n", __FUNCTION__);
472           exit (1);
473         }
474     }
475
476   r = pthread_barrier_wait (&b2);
477   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
478     {
479       printf ("%s: barrier_wait failed\n", __FUNCTION__);
480       exit (1);
481     }
482
483   fd_set rfs;
484   FD_ZERO (&rfs);
485   FD_SET (fd, &rfs);
486
487   int s;
488   pthread_cleanup_push (cl, NULL);
489
490   s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL);
491
492   pthread_cleanup_pop (0);
493
494   printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s,
495           strerror (errno));
496
497   exit (1);
498 }
499
500
501 static void *
502 tf_poll (void *arg)
503 {
504   int fd;
505   int r;
506
507   if (arg == NULL)
508     fd = fds[0];
509   else
510     {
511       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
512       tempfd = fd = mkstemp (fname);
513       if (fd == -1)
514         printf ("%s: mkstemp failed\n", __FUNCTION__);
515       unlink (fname);
516
517       r = pthread_barrier_wait (&b2);
518       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
519         {
520           printf ("%s: barrier_wait failed\n", __FUNCTION__);
521           exit (1);
522         }
523     }
524
525   r = pthread_barrier_wait (&b2);
526   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
527     {
528       printf ("%s: barrier_wait failed\n", __FUNCTION__);
529       exit (1);
530     }
531
532   struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
533
534   int s;
535   pthread_cleanup_push (cl, NULL);
536
537   s = poll (rfs, 1, -1);
538
539   pthread_cleanup_pop (0);
540
541   printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s,
542           strerror (errno));
543
544   exit (1);
545 }
546
547
548 static void *
549 tf_ppoll (void *arg)
550 {
551   int fd;
552   int r;
553
554   if (arg == NULL)
555     fd = fds[0];
556   else
557     {
558       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
559       tempfd = fd = mkstemp (fname);
560       if (fd == -1)
561         printf ("%s: mkstemp failed\n", __FUNCTION__);
562       unlink (fname);
563
564       r = pthread_barrier_wait (&b2);
565       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
566         {
567           printf ("%s: barrier_wait failed\n", __FUNCTION__);
568           exit (1);
569         }
570     }
571
572   r = pthread_barrier_wait (&b2);
573   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
574     {
575       printf ("%s: barrier_wait failed\n", __FUNCTION__);
576       exit (1);
577     }
578
579   struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
580
581   int s;
582   pthread_cleanup_push (cl, NULL);
583
584   s = ppoll (rfs, 1, NULL, NULL);
585
586   pthread_cleanup_pop (0);
587
588   printf ("%s: ppoll returns with %d (%s)\n", __FUNCTION__, s,
589           strerror (errno));
590
591   exit (1);
592 }
593
594
595 static void *
596 tf_wait (void *arg)
597 {
598   pid_t pid = fork ();
599   if (pid == -1)
600     {
601       puts ("fork failed");
602       exit (1);
603     }
604
605   if (pid == 0)
606     {
607       /* Make the program disappear after a while.  */
608       if (arg == NULL)
609         sleep (10);
610       exit (0);
611     }
612
613   int r;
614   if (arg != NULL)
615     {
616       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
617       while (nanosleep (&ts, &ts) != 0)
618         continue;
619
620       r = pthread_barrier_wait (&b2);
621       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
622         {
623           printf ("%s: barrier_wait failed\n", __FUNCTION__);
624           exit (1);
625         }
626     }
627
628   r = pthread_barrier_wait (&b2);
629   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
630     {
631       printf ("%s: barrier_wait failed\n", __FUNCTION__);
632       exit (1);
633     }
634
635   int s;
636   pthread_cleanup_push (cl, NULL);
637
638   s = wait (NULL);
639
640   pthread_cleanup_pop (0);
641
642   printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
643           strerror (errno));
644
645   exit (1);
646 }
647
648
649 static void *
650 tf_waitpid (void *arg)
651 {
652
653   pid_t pid = fork ();
654   if (pid == -1)
655     {
656       puts ("fork failed");
657       exit (1);
658     }
659
660   if (pid == 0)
661     {
662       /* Make the program disappear after a while.  */
663       if (arg == NULL)
664         sleep (10);
665       exit (0);
666     }
667
668   int r;
669   if (arg != NULL)
670     {
671       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
672       while (nanosleep (&ts, &ts) != 0)
673         continue;
674
675       r = pthread_barrier_wait (&b2);
676       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
677         {
678           printf ("%s: barrier_wait failed\n", __FUNCTION__);
679           exit (1);
680         }
681     }
682
683   r = pthread_barrier_wait (&b2);
684   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
685     {
686       printf ("%s: barrier_wait failed\n", __FUNCTION__);
687       exit (1);
688     }
689
690   int s;
691  pthread_cleanup_push (cl, NULL);
692
693   s = waitpid (-1, NULL, 0);
694
695   pthread_cleanup_pop (0);
696
697   printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
698           strerror (errno));
699
700   exit (1);
701 }
702
703
704 static void *
705 tf_waitid (void *arg)
706 {
707   pid_t pid = fork ();
708   if (pid == -1)
709     {
710       puts ("fork failed");
711       exit (1);
712     }
713
714   if (pid == 0)
715     {
716       /* Make the program disappear after a while.  */
717       if (arg == NULL)
718         sleep (10);
719       exit (0);
720     }
721
722   int r;
723   if (arg != NULL)
724     {
725       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
726       while (nanosleep (&ts, &ts) != 0)
727         continue;
728
729       r = pthread_barrier_wait (&b2);
730       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
731         {
732           printf ("%s: barrier_wait failed\n", __FUNCTION__);
733           exit (1);
734         }
735     }
736
737   r = pthread_barrier_wait (&b2);
738   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
739     {
740       printf ("%s: barrier_wait failed\n", __FUNCTION__);
741       exit (1);
742     }
743
744   int s;
745   pthread_cleanup_push (cl, NULL);
746
747 #ifndef WEXITED
748 # define WEXITED 0
749 #endif
750   siginfo_t si;
751   s = waitid (P_PID, pid, &si, WEXITED);
752
753   pthread_cleanup_pop (0);
754
755   printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
756           strerror (errno));
757
758   exit (1);
759 }
760
761
762 static void *
763 tf_sigpause (void *arg)
764 {
765   int r = pthread_barrier_wait (&b2);
766   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
767     {
768       printf ("%s: barrier_wait failed\n", __FUNCTION__);
769       exit (1);
770     }
771
772   if (arg != NULL)
773     {
774       r = pthread_barrier_wait (&b2);
775       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
776         {
777           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
778           exit (1);
779         }
780     }
781
782   pthread_cleanup_push (cl, NULL);
783
784   sigpause (SIGCANCEL);
785
786   pthread_cleanup_pop (0);
787
788   printf ("%s: sigpause returned\n", __FUNCTION__);
789
790   exit (1);
791 }
792
793
794 static void *
795 tf_sigsuspend (void *arg)
796 {
797   int r = pthread_barrier_wait (&b2);
798   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
799     {
800       printf ("%s: barrier_wait failed\n", __FUNCTION__);
801       exit (1);
802     }
803
804   if (arg != NULL)
805     {
806       r = pthread_barrier_wait (&b2);
807       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
808         {
809           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
810           exit (1);
811         }
812     }
813
814   pthread_cleanup_push (cl, NULL);
815
816   /* Just for fun block all signals.  */
817   sigset_t mask;
818   sigfillset (&mask);
819   sigsuspend (&mask);
820
821   pthread_cleanup_pop (0);
822
823   printf ("%s: sigsuspend returned\n", __FUNCTION__);
824
825   exit (1);
826 }
827
828
829 static void *
830 tf_sigwait (void *arg)
831 {
832   int r = pthread_barrier_wait (&b2);
833   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
834     {
835       printf ("%s: barrier_wait failed\n", __FUNCTION__);
836       exit (1);
837     }
838
839   if (arg != NULL)
840     {
841       r = pthread_barrier_wait (&b2);
842       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
843         {
844           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
845           exit (1);
846         }
847     }
848
849   /* Block SIGUSR1.  */
850   sigset_t mask;
851   sigemptyset (&mask);
852   sigaddset (&mask, SIGUSR1);
853   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
854     {
855       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
856       exit (1);
857     }
858
859   int sig;
860   pthread_cleanup_push (cl, NULL);
861
862   /* Wait for SIGUSR1.  */
863   sigwait (&mask, &sig);
864
865   pthread_cleanup_pop (0);
866
867   printf ("%s: sigwait returned with signal %d\n", __FUNCTION__, sig);
868
869   exit (1);
870 }
871
872
873 static void *
874 tf_sigwaitinfo (void *arg)
875 {
876   int r = pthread_barrier_wait (&b2);
877   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
878     {
879       printf ("%s: barrier_wait failed\n", __FUNCTION__);
880       exit (1);
881     }
882
883   if (arg != NULL)
884     {
885       r = pthread_barrier_wait (&b2);
886       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
887         {
888           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
889           exit (1);
890         }
891     }
892
893   /* Block SIGUSR1.  */
894   sigset_t mask;
895   sigemptyset (&mask);
896   sigaddset (&mask, SIGUSR1);
897   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
898     {
899       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
900       exit (1);
901     }
902
903   siginfo_t info;
904   pthread_cleanup_push (cl, NULL);
905
906   /* Wait for SIGUSR1.  */
907   sigwaitinfo (&mask, &info);
908
909   pthread_cleanup_pop (0);
910
911   printf ("%s: sigwaitinfo returned with signal %d\n", __FUNCTION__,
912           info.si_signo);
913
914   exit (1);
915 }
916
917
918 static void *
919 tf_sigtimedwait (void *arg)
920 {
921   int r = pthread_barrier_wait (&b2);
922   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
923     {
924       printf ("%s: barrier_wait failed\n", __FUNCTION__);
925       exit (1);
926     }
927
928   if (arg != NULL)
929     {
930       r = pthread_barrier_wait (&b2);
931       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
932         {
933           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
934           exit (1);
935         }
936     }
937
938   /* Block SIGUSR1.  */
939   sigset_t mask;
940   sigemptyset (&mask);
941   sigaddset (&mask, SIGUSR1);
942   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
943     {
944       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
945       exit (1);
946     }
947
948   /* Wait for SIGUSR1.  */
949   siginfo_t info;
950   struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
951   pthread_cleanup_push (cl, NULL);
952
953   sigtimedwait (&mask, &info, &ts);
954
955   pthread_cleanup_pop (0);
956
957   printf ("%s: sigtimedwait returned with signal %d\n", __FUNCTION__,
958           info.si_signo);
959
960   exit (1);
961 }
962
963
964 static void *
965 tf_pause (void *arg)
966 {
967   int r = pthread_barrier_wait (&b2);
968   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
969     {
970       printf ("%s: barrier_wait failed\n", __FUNCTION__);
971       exit (1);
972     }
973
974   if (arg != NULL)
975     {
976       r = pthread_barrier_wait (&b2);
977       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
978         {
979           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
980           exit (1);
981         }
982     }
983
984   pthread_cleanup_push (cl, NULL);
985
986   pause ();
987
988   pthread_cleanup_pop (0);
989
990   printf ("%s: pause returned\n", __FUNCTION__);
991
992   exit (1);
993 }
994
995
996 static void *
997 tf_accept (void *arg)
998 {
999   int tfd;
1000   struct sockaddr_un sun;
1001   /* To test a non-blocking accept call we make the call file by using
1002      a datagrame socket.  */
1003   int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
1004
1005   tempfd = socket (AF_UNIX, pf, 0);
1006   if (tempfd == -1)
1007     {
1008       printf ("%s: socket call failed\n", __FUNCTION__);
1009       exit (1);
1010     }
1011
1012   int tries = 0;
1013   do
1014     {
1015       if (++tries > 10)
1016         {
1017           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1018         }
1019
1020       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
1021       tfd = mkstemp(sun.sun_path);
1022       if (tfd < 0)
1023         {
1024           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1025           exit (1);
1026         }
1027       close(tfd);
1028       sun.sun_family = AF_UNIX;
1029     }
1030   while (bind (tempfd, (struct sockaddr *) &sun,
1031                offsetof (struct sockaddr_un, sun_path)
1032                + strlen (sun.sun_path) + 1) != 0);
1033
1034   unlink (sun.sun_path);
1035
1036   listen (tempfd, 5);
1037
1038   socklen_t len = sizeof (sun);
1039
1040   int r = pthread_barrier_wait (&b2);
1041   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1042     {
1043       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1044       exit (1);
1045     }
1046
1047   if (arg != NULL)
1048     {
1049       r = pthread_barrier_wait (&b2);
1050       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1051         {
1052           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1053           exit (1);
1054         }
1055     }
1056
1057   pthread_cleanup_push (cl, NULL);
1058
1059   accept (tempfd, (struct sockaddr *) &sun, &len);
1060
1061   pthread_cleanup_pop (0);
1062
1063   printf ("%s: accept returned\n", __FUNCTION__);
1064
1065   exit (1);
1066 }
1067
1068
1069 static void *
1070 tf_send (void *arg)
1071 {
1072   int tfd;
1073   struct sockaddr_un sun;
1074
1075   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1076   if (tempfd == -1)
1077     {
1078       printf ("%s: first socket call failed\n", __FUNCTION__);
1079       exit (1);
1080     }
1081
1082   int tries = 0;
1083   do
1084     {
1085       if (++tries > 10)
1086         {
1087           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1088         }
1089
1090       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1091       tfd = mkstemp(sun.sun_path);
1092       if (tfd < 0)
1093         {
1094           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1095           exit (1);
1096         }
1097       close(tfd);
1098       sun.sun_family = AF_UNIX;
1099     }
1100   while (bind (tempfd, (struct sockaddr *) &sun,
1101                offsetof (struct sockaddr_un, sun_path)
1102                + strlen (sun.sun_path) + 1) != 0);
1103
1104   listen (tempfd, 5);
1105
1106   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1107   if (tempfd2 == -1)
1108     {
1109       printf ("%s: second socket call failed\n", __FUNCTION__);
1110       exit (1);
1111     }
1112
1113   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1114     {
1115       printf ("%s: connect failed\n", __FUNCTION__);
1116       exit(1);
1117     }
1118
1119   unlink (sun.sun_path);
1120
1121   int r = pthread_barrier_wait (&b2);
1122   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1123     {
1124       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1125       exit (1);
1126     }
1127
1128   if (arg != NULL)
1129     {
1130       r = pthread_barrier_wait (&b2);
1131       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1132         {
1133           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1134           exit (1);
1135         }
1136     }
1137
1138   pthread_cleanup_push (cl, NULL);
1139
1140   /* Very large block, so that the send call blocks.  */
1141   char mem[700000];
1142
1143   send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
1144
1145   pthread_cleanup_pop (0);
1146
1147   printf ("%s: send returned\n", __FUNCTION__);
1148
1149   exit (1);
1150 }
1151
1152
1153 static void *
1154 tf_recv (void *arg)
1155 {
1156   int tfd;
1157   struct sockaddr_un sun;
1158
1159   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1160   if (tempfd == -1)
1161     {
1162       printf ("%s: first socket call failed\n", __FUNCTION__);
1163       exit (1);
1164     }
1165
1166   int tries = 0;
1167   do
1168     {
1169       if (++tries > 10)
1170         {
1171           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1172         }
1173
1174       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
1175       tfd = mkstemp(sun.sun_path);
1176       if (tfd < 0)
1177         {
1178           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1179           exit (1);
1180         }
1181       close(tfd);
1182       sun.sun_family = AF_UNIX;
1183     }
1184   while (bind (tempfd, (struct sockaddr *) &sun,
1185                offsetof (struct sockaddr_un, sun_path)
1186                + strlen (sun.sun_path) + 1) != 0);
1187
1188   listen (tempfd, 5);
1189
1190   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1191   if (tempfd2 == -1)
1192     {
1193       printf ("%s: second socket call failed\n", __FUNCTION__);
1194       exit (1);
1195     }
1196
1197   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1198     {
1199       printf ("%s: connect failed\n", __FUNCTION__);
1200       exit(1);
1201     }
1202
1203   unlink (sun.sun_path);
1204
1205   int r = pthread_barrier_wait (&b2);
1206   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1207     {
1208       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1209       exit (1);
1210     }
1211
1212   if (arg != NULL)
1213     {
1214       r = pthread_barrier_wait (&b2);
1215       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1216         {
1217           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1218           exit (1);
1219         }
1220     }
1221
1222   pthread_cleanup_push (cl, NULL);
1223
1224   char mem[70];
1225
1226   recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
1227
1228   pthread_cleanup_pop (0);
1229
1230   printf ("%s: recv returned\n", __FUNCTION__);
1231
1232   exit (1);
1233 }
1234
1235
1236 static void *
1237 tf_recvfrom (void *arg)
1238 {
1239   int tfd;
1240   struct sockaddr_un sun;
1241
1242   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1243   if (tempfd == -1)
1244     {
1245       printf ("%s: first socket call failed\n", __FUNCTION__);
1246       exit (1);
1247     }
1248
1249   int tries = 0;
1250   do
1251     {
1252       if (++tries > 10)
1253         {
1254           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1255         }
1256
1257       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
1258       tfd = mkstemp(sun.sun_path);
1259       if (tfd < 0)
1260         {
1261           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1262           exit (1);
1263         }
1264       close(tfd);
1265       sun.sun_family = AF_UNIX;
1266     }
1267   while (bind (tempfd, (struct sockaddr *) &sun,
1268                offsetof (struct sockaddr_un, sun_path)
1269                + strlen (sun.sun_path) + 1) != 0);
1270
1271   tempfname = strdup (sun.sun_path);
1272
1273   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1274   if (tempfd2 == -1)
1275     {
1276       printf ("%s: second socket call failed\n", __FUNCTION__);
1277       exit (1);
1278     }
1279
1280   int r = pthread_barrier_wait (&b2);
1281   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1282     {
1283       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1284       exit (1);
1285     }
1286
1287   if (arg != NULL)
1288     {
1289       r = pthread_barrier_wait (&b2);
1290       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1291         {
1292           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1293           exit (1);
1294         }
1295     }
1296
1297   pthread_cleanup_push (cl, NULL);
1298
1299   char mem[70];
1300   socklen_t len = sizeof (sun);
1301
1302   recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
1303             (struct sockaddr *) &sun, &len);
1304
1305   pthread_cleanup_pop (0);
1306
1307   printf ("%s: recvfrom returned\n", __FUNCTION__);
1308
1309   exit (1);
1310 }
1311
1312
1313 static void *
1314 tf_recvmsg (void *arg)
1315 {
1316   int tfd;
1317   struct sockaddr_un sun;
1318
1319   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1320   if (tempfd == -1)
1321     {
1322       printf ("%s: first socket call failed\n", __FUNCTION__);
1323       exit (1);
1324     }
1325
1326   int tries = 0;
1327   do
1328     {
1329       if (++tries > 10)
1330         {
1331           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1332         }
1333
1334       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
1335       tfd = mkstemp(sun.sun_path);
1336       if (tfd < 0)
1337         {
1338           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1339           exit (1);
1340         }
1341       close(tfd);
1342       sun.sun_family = AF_UNIX;
1343     }
1344   while (bind (tempfd, (struct sockaddr *) &sun,
1345                offsetof (struct sockaddr_un, sun_path)
1346                + strlen (sun.sun_path) + 1) != 0);
1347
1348   tempfname = strdup (sun.sun_path);
1349
1350   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1351   if (tempfd2 == -1)
1352     {
1353       printf ("%s: second socket call failed\n", __FUNCTION__);
1354       exit (1);
1355     }
1356
1357   int r = pthread_barrier_wait (&b2);
1358   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1359     {
1360       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1361       exit (1);
1362     }
1363
1364   if (arg != NULL)
1365     {
1366       r = pthread_barrier_wait (&b2);
1367       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1368         {
1369           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1370           exit (1);
1371         }
1372     }
1373
1374   pthread_cleanup_push (cl, NULL);
1375
1376   char mem[70];
1377   struct iovec iov[1];
1378   iov[0].iov_base = mem;
1379   iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
1380
1381   struct msghdr m;
1382   m.msg_name = &sun;
1383   m.msg_namelen = sizeof (sun);
1384   m.msg_iov = iov;
1385   m.msg_iovlen = 1;
1386   m.msg_control = NULL;
1387   m.msg_controllen = 0;
1388
1389   recvmsg (tempfd2, &m, 0);
1390
1391   pthread_cleanup_pop (0);
1392
1393   printf ("%s: recvmsg returned\n", __FUNCTION__);
1394
1395   exit (1);
1396 }
1397
1398
1399 static void *
1400 tf_open (void *arg)
1401 {
1402   if (arg == NULL)
1403     // XXX If somebody can provide a portable test case in which open()
1404     // blocks we can enable this test to run in both rounds.
1405     abort ();
1406
1407   int r = pthread_barrier_wait (&b2);
1408   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1409     {
1410       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1411       exit (1);
1412     }
1413
1414   r = pthread_barrier_wait (&b2);
1415   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1416     {
1417       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1418       exit (1);
1419     }
1420
1421   pthread_cleanup_push (cl, NULL);
1422
1423   open ("Makefile", O_RDONLY);
1424
1425   pthread_cleanup_pop (0);
1426
1427   printf ("%s: open returned\n", __FUNCTION__);
1428
1429   exit (1);
1430 }
1431
1432
1433 static void *
1434 tf_close (void *arg)
1435 {
1436   if (arg == NULL)
1437     // XXX If somebody can provide a portable test case in which close()
1438     // blocks we can enable this test to run in both rounds.
1439     abort ();
1440
1441   char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
1442   tempfd = mkstemp (fname);
1443   if (tempfd == -1)
1444     {
1445       printf ("%s: mkstemp failed\n", __FUNCTION__);
1446       exit (1);
1447     }
1448   unlink (fname);
1449
1450   int r = pthread_barrier_wait (&b2);
1451   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1452     {
1453       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1454       exit (1);
1455     }
1456
1457   r = pthread_barrier_wait (&b2);
1458   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1459     {
1460       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1461       exit (1);
1462     }
1463
1464   pthread_cleanup_push (cl, NULL);
1465
1466   close (tempfd);
1467
1468   pthread_cleanup_pop (0);
1469
1470   printf ("%s: close returned\n", __FUNCTION__);
1471
1472   exit (1);
1473 }
1474
1475
1476 static void *
1477 tf_pread (void *arg)
1478 {
1479   if (arg == NULL)
1480     // XXX If somebody can provide a portable test case in which pread()
1481     // blocks we can enable this test to run in both rounds.
1482     abort ();
1483
1484   tempfd = open ("Makefile", O_RDONLY);
1485   if (tempfd == -1)
1486     {
1487       printf ("%s: cannot open Makefile\n", __FUNCTION__);
1488       exit (1);
1489     }
1490
1491   int r = pthread_barrier_wait (&b2);
1492   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1493     {
1494       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1495       exit (1);
1496     }
1497
1498   r = pthread_barrier_wait (&b2);
1499   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1500     {
1501       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1502       exit (1);
1503     }
1504
1505   pthread_cleanup_push (cl, NULL);
1506
1507   char mem[10];
1508   pread (tempfd, mem, sizeof (mem), 0);
1509
1510   pthread_cleanup_pop (0);
1511
1512   printf ("%s: pread returned\n", __FUNCTION__);
1513
1514   exit (1);
1515 }
1516
1517
1518 static void *
1519 tf_pwrite (void *arg)
1520 {
1521   if (arg == NULL)
1522     // XXX If somebody can provide a portable test case in which pwrite()
1523     // blocks we can enable this test to run in both rounds.
1524     abort ();
1525
1526   char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1527   tempfd = mkstemp (fname);
1528   if (tempfd == -1)
1529     {
1530       printf ("%s: mkstemp failed\n", __FUNCTION__);
1531       exit (1);
1532     }
1533   unlink (fname);
1534
1535   int r = pthread_barrier_wait (&b2);
1536   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1537     {
1538       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1539       exit (1);
1540     }
1541
1542   r = pthread_barrier_wait (&b2);
1543   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1544     {
1545       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1546       exit (1);
1547     }
1548
1549   pthread_cleanup_push (cl, NULL);
1550
1551   char mem[10];
1552   pwrite (tempfd, mem, sizeof (mem), 0);
1553
1554   pthread_cleanup_pop (0);
1555
1556   printf ("%s: pwrite returned\n", __FUNCTION__);
1557
1558   exit (1);
1559 }
1560
1561
1562 static void *
1563 tf_fsync (void *arg)
1564 {
1565   if (arg == NULL)
1566     // XXX If somebody can provide a portable test case in which fsync()
1567     // blocks we can enable this test to run in both rounds.
1568     abort ();
1569
1570   tempfd = open ("Makefile", O_RDONLY);
1571   if (tempfd == -1)
1572     {
1573       printf ("%s: cannot open Makefile\n", __FUNCTION__);
1574       exit (1);
1575     }
1576
1577   int r = pthread_barrier_wait (&b2);
1578   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1579     {
1580       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1581       exit (1);
1582     }
1583
1584   r = pthread_barrier_wait (&b2);
1585   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1586     {
1587       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1588       exit (1);
1589     }
1590
1591   pthread_cleanup_push (cl, NULL);
1592
1593   fsync (tempfd);
1594
1595   pthread_cleanup_pop (0);
1596
1597   printf ("%s: fsync returned\n", __FUNCTION__);
1598
1599   exit (1);
1600 }
1601
1602
1603 static void *
1604 tf_fdatasync (void *arg)
1605 {
1606   if (arg == NULL)
1607     // XXX If somebody can provide a portable test case in which fdatasync()
1608     // blocks we can enable this test to run in both rounds.
1609     abort ();
1610
1611   tempfd = open ("Makefile", O_RDONLY);
1612   if (tempfd == -1)
1613     {
1614       printf ("%s: cannot open Makefile\n", __FUNCTION__);
1615       exit (1);
1616     }
1617
1618   int r = pthread_barrier_wait (&b2);
1619   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1620     {
1621       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1622       exit (1);
1623     }
1624
1625   r = pthread_barrier_wait (&b2);
1626   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1627     {
1628       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1629       exit (1);
1630     }
1631
1632   pthread_cleanup_push (cl, NULL);
1633
1634   fdatasync (tempfd);
1635
1636   pthread_cleanup_pop (0);
1637
1638   printf ("%s: fdatasync returned\n", __FUNCTION__);
1639
1640   exit (1);
1641 }
1642
1643
1644 static void *
1645 tf_msync (void *arg)
1646 {
1647   if (arg == NULL)
1648     // XXX If somebody can provide a portable test case in which msync()
1649     // blocks we can enable this test to run in both rounds.
1650     abort ();
1651
1652   tempfd = open ("Makefile", O_RDONLY);
1653   if (tempfd == -1)
1654     {
1655       printf ("%s: cannot open Makefile\n", __FUNCTION__);
1656       exit (1);
1657     }
1658   void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
1659   if (p == MAP_FAILED)
1660     {
1661       printf ("%s: mmap failed\n", __FUNCTION__);
1662       exit (1);
1663     }
1664
1665   int r = pthread_barrier_wait (&b2);
1666   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1667     {
1668       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1669       exit (1);
1670     }
1671
1672   r = pthread_barrier_wait (&b2);
1673   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1674     {
1675       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1676       exit (1);
1677     }
1678
1679   pthread_cleanup_push (cl, NULL);
1680
1681   msync (p, 10, 0);
1682
1683   pthread_cleanup_pop (0);
1684
1685   printf ("%s: msync returned\n", __FUNCTION__);
1686
1687   exit (1);
1688 }
1689
1690
1691 static void *
1692 tf_sendto (void *arg)
1693 {
1694   int tfd;
1695   if (arg == NULL)
1696     // XXX If somebody can provide a portable test case in which sendto()
1697     // blocks we can enable this test to run in both rounds.
1698     abort ();
1699
1700   struct sockaddr_un sun;
1701
1702   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1703   if (tempfd == -1)
1704     {
1705       printf ("%s: first socket call failed\n", __FUNCTION__);
1706       exit (1);
1707     }
1708
1709   int tries = 0;
1710   do
1711     {
1712       if (++tries > 10)
1713         {
1714           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1715         }
1716
1717       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
1718       tfd = mkstemp(sun.sun_path);
1719       if (tfd < 0)
1720         {
1721           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1722           exit (1);
1723         }
1724       close(tfd);
1725       sun.sun_family = AF_UNIX;
1726     }
1727   while (bind (tempfd, (struct sockaddr *) &sun,
1728                offsetof (struct sockaddr_un, sun_path)
1729                + strlen (sun.sun_path) + 1) != 0);
1730   tempfname = strdup (sun.sun_path);
1731
1732   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1733   if (tempfd2 == -1)
1734     {
1735       printf ("%s: second socket call failed\n", __FUNCTION__);
1736       exit (1);
1737     }
1738
1739   int r = pthread_barrier_wait (&b2);
1740   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1741     {
1742       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1743       exit (1);
1744     }
1745
1746   r = pthread_barrier_wait (&b2);
1747   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1748     {
1749       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1750       exit (1);
1751     }
1752
1753   pthread_cleanup_push (cl, NULL);
1754
1755   char mem[1];
1756
1757   sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
1758           (struct sockaddr *) &sun,
1759           offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
1760
1761   pthread_cleanup_pop (0);
1762
1763   printf ("%s: sendto returned\n", __FUNCTION__);
1764
1765   exit (1);
1766 }
1767
1768
1769 static void *
1770 tf_sendmsg (void *arg)
1771 {
1772   int tfd;
1773   if (arg == NULL)
1774     // XXX If somebody can provide a portable test case in which sendmsg()
1775     // blocks we can enable this test to run in both rounds.
1776     abort ();
1777
1778   struct sockaddr_un sun;
1779
1780   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1781   if (tempfd == -1)
1782     {
1783       printf ("%s: first socket call failed\n", __FUNCTION__);
1784       exit (1);
1785     }
1786
1787   int tries = 0;
1788   do
1789     {
1790       if (++tries > 10)
1791         {
1792           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1793         }
1794
1795       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
1796       tfd = mkstemp(sun.sun_path);
1797       if (tfd < 0)
1798         {
1799           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1800           exit (1);
1801         }
1802       close(tfd);
1803       sun.sun_family = AF_UNIX;
1804     }
1805   while (bind (tempfd, (struct sockaddr *) &sun,
1806                offsetof (struct sockaddr_un, sun_path)
1807                + strlen (sun.sun_path) + 1) != 0);
1808   tempfname = strdup (sun.sun_path);
1809
1810   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1811   if (tempfd2 == -1)
1812     {
1813       printf ("%s: second socket call failed\n", __FUNCTION__);
1814       exit (1);
1815     }
1816
1817   int r = pthread_barrier_wait (&b2);
1818   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1819     {
1820       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1821       exit (1);
1822     }
1823
1824   r = pthread_barrier_wait (&b2);
1825   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1826     {
1827       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1828       exit (1);
1829     }
1830
1831   pthread_cleanup_push (cl, NULL);
1832
1833   char mem[1];
1834   struct iovec iov[1];
1835   iov[0].iov_base = mem;
1836   iov[0].iov_len = 1;
1837
1838   struct msghdr m;
1839   m.msg_name = &sun;
1840   m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
1841                    + strlen (sun.sun_path) + 1);
1842   m.msg_iov = iov;
1843   m.msg_iovlen = 1;
1844   m.msg_control = NULL;
1845   m.msg_controllen = 0;
1846
1847   sendmsg (tempfd2, &m, 0);
1848
1849   pthread_cleanup_pop (0);
1850
1851   printf ("%s: sendmsg returned\n", __FUNCTION__);
1852
1853   exit (1);
1854 }
1855
1856
1857 static void *
1858 tf_creat (void *arg)
1859 {
1860   if (arg == NULL)
1861     // XXX If somebody can provide a portable test case in which sendmsg()
1862     // blocks we can enable this test to run in both rounds.
1863     abort ();
1864
1865   int r = pthread_barrier_wait (&b2);
1866   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1867     {
1868       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1869       exit (1);
1870     }
1871
1872   r = pthread_barrier_wait (&b2);
1873   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1874     {
1875       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1876       exit (1);
1877     }
1878
1879   pthread_cleanup_push (cl, NULL);
1880
1881   creat ("tmp/tst-cancel-4-should-not-exist", 0666);
1882
1883   pthread_cleanup_pop (0);
1884
1885   printf ("%s: creat returned\n", __FUNCTION__);
1886
1887   exit (1);
1888 }
1889
1890
1891 static void *
1892 tf_connect (void *arg)
1893 {
1894   int tfd;
1895   if (arg == NULL)
1896     // XXX If somebody can provide a portable test case in which connect()
1897     // blocks we can enable this test to run in both rounds.
1898     abort ();
1899
1900   struct sockaddr_un sun;
1901
1902   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1903   if (tempfd == -1)
1904     {
1905       printf ("%s: first socket call failed\n", __FUNCTION__);
1906       exit (1);
1907     }
1908
1909   int tries = 0;
1910   do
1911     {
1912       if (++tries > 10)
1913         {
1914           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1915         }
1916
1917       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1918       tfd = mkstemp(sun.sun_path);
1919       if (tfd < 0)
1920         {
1921           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1922           exit (1);
1923         }
1924       close(tfd);
1925       sun.sun_family = AF_UNIX;
1926     }
1927   while (bind (tempfd, (struct sockaddr *) &sun,
1928                offsetof (struct sockaddr_un, sun_path)
1929                + strlen (sun.sun_path) + 1) != 0);
1930   tempfname = strdup (sun.sun_path);
1931
1932   listen (tempfd, 5);
1933
1934   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1935   if (tempfd2 == -1)
1936     {
1937       printf ("%s: second socket call failed\n", __FUNCTION__);
1938       exit (1);
1939     }
1940
1941   int r = pthread_barrier_wait (&b2);
1942   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1943     {
1944       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1945       exit (1);
1946     }
1947
1948   if (arg != NULL)
1949     {
1950       r = pthread_barrier_wait (&b2);
1951       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1952         {
1953           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1954           exit (1);
1955         }
1956     }
1957
1958   pthread_cleanup_push (cl, NULL);
1959
1960   connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
1961
1962   pthread_cleanup_pop (0);
1963
1964   printf ("%s: connect returned\n", __FUNCTION__);
1965
1966   exit (1);
1967 }
1968
1969
1970 static void *
1971 tf_tcdrain (void *arg)
1972 {
1973   if (arg == NULL)
1974     // XXX If somebody can provide a portable test case in which tcdrain()
1975     // blocks we can enable this test to run in both rounds.
1976     abort ();
1977
1978   int r = pthread_barrier_wait (&b2);
1979   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1980     {
1981       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1982       exit (1);
1983     }
1984
1985   if (arg != NULL)
1986     {
1987       r = pthread_barrier_wait (&b2);
1988       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1989         {
1990           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1991           exit (1);
1992         }
1993     }
1994
1995   pthread_cleanup_push (cl, NULL);
1996
1997   /* Regardless of stderr being a terminal, the tcdrain call should be
1998      canceled.  */
1999   tcdrain (STDERR_FILENO);
2000
2001   pthread_cleanup_pop (0);
2002
2003   printf ("%s: tcdrain returned\n", __FUNCTION__);
2004
2005   exit (1);
2006 }
2007
2008
2009 static void *
2010 tf_msgrcv (void *arg)
2011 {
2012   tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
2013   if (tempmsg == -1)
2014     {
2015       printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
2016       exit (1);
2017     }
2018
2019   int r = pthread_barrier_wait (&b2);
2020   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2021     {
2022       printf ("%s: barrier_wait failed\n", __FUNCTION__);
2023       exit (1);
2024     }
2025
2026   if (arg != NULL)
2027     {
2028       r = pthread_barrier_wait (&b2);
2029       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2030         {
2031           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
2032           exit (1);
2033         }
2034     }
2035
2036   ssize_t s;
2037
2038   pthread_cleanup_push (cl, NULL);
2039
2040   struct
2041   {
2042     long int type;
2043     char mem[10];
2044   } m;
2045   int randnr;
2046   /* We need a positive random number.  */
2047   do
2048     randnr = random () % 64000;
2049   while (randnr <= 0);
2050   do
2051     {
2052       errno = 0;
2053       s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
2054     }
2055   while (errno == EIDRM || errno == EINTR);
2056
2057   pthread_cleanup_pop (0);
2058
2059   printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);
2060
2061   msgctl (tempmsg, IPC_RMID, NULL);
2062
2063   exit (1);
2064 }
2065
2066
2067 static void *
2068 tf_msgsnd (void *arg)
2069 {
2070   if (arg == NULL)
2071     // XXX If somebody can provide a portable test case in which msgsnd()
2072     // blocks we can enable this test to run in both rounds.
2073     abort ();
2074
2075   tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
2076   if (tempmsg == -1)
2077     {
2078       printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
2079       exit (1);
2080     }
2081
2082   int r = pthread_barrier_wait (&b2);
2083   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2084     {
2085       printf ("%s: barrier_wait failed\n", __FUNCTION__);
2086       exit (1);
2087     }
2088
2089   r = pthread_barrier_wait (&b2);
2090   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2091     {
2092       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
2093       exit (1);
2094     }
2095
2096   pthread_cleanup_push (cl, NULL);
2097
2098   struct
2099   {
2100     long int type;
2101     char mem[1];
2102   } m;
2103   /* We need a positive random number.  */
2104   do
2105     m.type = random () % 64000;
2106   while (m.type <= 0);
2107   msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
2108
2109   pthread_cleanup_pop (0);
2110
2111   printf ("%s: msgsnd returned\n", __FUNCTION__);
2112
2113   msgctl (tempmsg, IPC_RMID, NULL);
2114
2115   exit (1);
2116 }
2117
2118
2119 static struct
2120 {
2121   const char *name;
2122   void *(*tf) (void *);
2123   int nb;
2124   int only_early;
2125 } tests[] =
2126 {
2127 #define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early }
2128   ADD_TEST (read, 2, 0),
2129   ADD_TEST (readv, 2, 0),
2130   ADD_TEST (select, 2, 0),
2131   ADD_TEST (pselect, 2, 0),
2132   ADD_TEST (poll, 2, 0),
2133   ADD_TEST (ppoll, 2, 0),
2134   ADD_TEST (write, 2, 0),
2135   ADD_TEST (writev, 2, 0),
2136   ADD_TEST (sleep, 2, 0),
2137   ADD_TEST (usleep, 2, 0),
2138   ADD_TEST (nanosleep, 2, 0),
2139   ADD_TEST (wait, 2, 0),
2140   ADD_TEST (waitid, 2, 0),
2141   ADD_TEST (waitpid, 2, 0),
2142   ADD_TEST (sigpause, 2, 0),
2143   ADD_TEST (sigsuspend, 2, 0),
2144   ADD_TEST (sigwait, 2, 0),
2145   ADD_TEST (sigwaitinfo, 2, 0),
2146   ADD_TEST (sigtimedwait, 2, 0),
2147   ADD_TEST (pause, 2, 0),
2148   ADD_TEST (accept, 2, 0),
2149   ADD_TEST (send, 2, 0),
2150   ADD_TEST (recv, 2, 0),
2151   ADD_TEST (recvfrom, 2, 0),
2152   ADD_TEST (recvmsg, 2, 0),
2153   ADD_TEST (open, 2, 1),
2154   ADD_TEST (close, 2, 1),
2155   ADD_TEST (pread, 2, 1),
2156   ADD_TEST (pwrite, 2, 1),
2157   ADD_TEST (fsync, 2, 1),
2158   ADD_TEST (fdatasync, 2, 1),
2159   ADD_TEST (msync, 2, 1),
2160   ADD_TEST (sendto, 2, 1),
2161   ADD_TEST (sendmsg, 2, 1),
2162   ADD_TEST (creat, 2, 1),
2163   ADD_TEST (connect, 2, 1),
2164   ADD_TEST (tcdrain, 2, 1),
2165   ADD_TEST (msgrcv, 2, 0),
2166   ADD_TEST (msgsnd, 2, 1),
2167 };
2168 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
2169
2170
2171 static int
2172 do_test (void)
2173 {
2174   int val;
2175   socklen_t len;
2176
2177   if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
2178     {
2179       perror ("socketpair");
2180       exit (1);
2181     }
2182
2183   val = 1;
2184   len = sizeof(val);
2185   setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2186   if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
2187     {
2188       perror ("getsockopt");
2189       exit (1);
2190     }
2191   if (val >= WRITE_BUFFER_SIZE)
2192     {
2193       puts ("minimum write buffer size too large");
2194       exit (1);
2195     }
2196   setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2197
2198   int result = 0;
2199   size_t cnt;
2200   for (cnt = 0; cnt < ntest_tf; ++cnt)
2201     {
2202       if (tests[cnt].only_early)
2203         continue;
2204
2205       if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2206         {
2207           puts ("b2 init failed");
2208           exit (1);
2209         }
2210
2211       /* Reset the counter for the cleanup handler.  */
2212       cl_called = 0;
2213
2214       pthread_t th;
2215       if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
2216         {
2217           printf ("create for '%s' test failed\n", tests[cnt].name);
2218           result = 1;
2219           continue;
2220         }
2221
2222       int r = pthread_barrier_wait (&b2);
2223       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2224         {
2225           printf ("%s: barrier_wait failed\n", __FUNCTION__);
2226           result = 1;
2227           continue;
2228         }
2229
2230       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
2231       while (nanosleep (&ts, &ts) != 0)
2232         continue;
2233
2234       if (pthread_cancel (th) != 0)
2235         {
2236           printf ("cancel for '%s' failed\n", tests[cnt].name);
2237           result = 1;
2238           continue;
2239         }
2240
2241       void *status;
2242       if (pthread_join (th, &status) != 0)
2243         {
2244           printf ("join for '%s' failed\n", tests[cnt].name);
2245           result = 1;
2246           continue;
2247         }
2248       if (status != PTHREAD_CANCELED)
2249         {
2250           printf ("thread for '%s' not canceled\n", tests[cnt].name);
2251           result = 1;
2252           continue;
2253         }
2254
2255       if (pthread_barrier_destroy (&b2) != 0)
2256         {
2257           puts ("barrier_destroy failed");
2258           result = 1;
2259           continue;
2260         }
2261
2262       if (cl_called == 0)
2263         {
2264           printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2265           result = 1;
2266           continue;
2267         }
2268       if (cl_called > 1)
2269         {
2270           printf ("cleanup handler called more than once for '%s'\n",
2271                   tests[cnt].name);
2272           result = 1;
2273           continue;
2274         }
2275
2276       printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);
2277
2278       if (tempfd != -1)
2279         {
2280           close (tempfd);
2281           tempfd = -1;
2282         }
2283       if (tempfd2 != -1)
2284         {
2285           close (tempfd2);
2286           tempfd2 = -1;
2287         }
2288       if (tempfname != NULL)
2289         {
2290           unlink (tempfname);
2291           free (tempfname);
2292           tempfname = NULL;
2293         }
2294       if (tempmsg != -1)
2295         {
2296           msgctl (tempmsg, IPC_RMID, NULL);
2297           tempmsg = -1;
2298         }
2299     }
2300
2301   for (cnt = 0; cnt < ntest_tf; ++cnt)
2302     {
2303       if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2304         {
2305           puts ("b2 init failed");
2306           exit (1);
2307         }
2308
2309       /* Reset the counter for the cleanup handler.  */
2310       cl_called = 0;
2311
2312       pthread_t th;
2313       if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
2314         {
2315           printf ("create for '%s' test failed\n", tests[cnt].name);
2316           result = 1;
2317           continue;
2318         }
2319
2320       int r = pthread_barrier_wait (&b2);
2321       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2322         {
2323           printf ("%s: barrier_wait failed\n", __FUNCTION__);
2324           result = 1;
2325           continue;
2326         }
2327
2328       if (pthread_cancel (th) != 0)
2329         {
2330           printf ("cancel for '%s' failed\n", tests[cnt].name);
2331           result = 1;
2332           continue;
2333         }
2334
2335       r = pthread_barrier_wait (&b2);
2336       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2337         {
2338           printf ("%s: barrier_wait failed\n", __FUNCTION__);
2339           result = 1;
2340           continue;
2341         }
2342
2343       void *status;
2344       if (pthread_join (th, &status) != 0)
2345         {
2346           printf ("join for '%s' failed\n", tests[cnt].name);
2347           result = 1;
2348           continue;
2349         }
2350       if (status != PTHREAD_CANCELED)
2351         {
2352           printf ("thread for '%s' not canceled\n", tests[cnt].name);
2353           result = 1;
2354           continue;
2355         }
2356
2357       if (pthread_barrier_destroy (&b2) != 0)
2358         {
2359           puts ("barrier_destroy failed");
2360           result = 1;
2361           continue;
2362         }
2363
2364       if (cl_called == 0)
2365         {
2366           printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2367           result = 1;
2368           continue;
2369         }
2370       if (cl_called > 1)
2371         {
2372           printf ("cleanup handler called more than once for '%s'\n",
2373                   tests[cnt].name);
2374           result = 1;
2375           continue;
2376         }
2377
2378       printf ("early cancel test of '%s' successful\n", tests[cnt].name);
2379
2380       if (tempfd != -1)
2381         {
2382           close (tempfd);
2383           tempfd = -1;
2384         }
2385       if (tempfd2 != -1)
2386         {
2387           close (tempfd2);
2388           tempfd2 = -1;
2389         }
2390       if (tempfname != NULL)
2391         {
2392           unlink (tempfname);
2393           free (tempfname);
2394           tempfname = NULL;
2395         }
2396       if (tempmsg != -1)
2397         {
2398           msgctl (tempmsg, IPC_RMID, NULL);
2399           tempmsg = -1;
2400         }
2401     }
2402
2403   return result;
2404 }
2405
2406 #define TIMEOUT 60
2407 #define TEST_FUNCTION do_test ()
2408 #include "../test-skeleton.c"