OSDN Git Service

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