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