]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/test/nptl/tst-cancel4.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / 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.  We need to use
762      __xpg_sigpause since otherwise we will get the BSD version.  */
763   //__xpg_sigpause (SIGCANCEL);
764
765   __sigpause (SIGCANCEL, 1);
766
767   pthread_cleanup_pop (0);
768
769   printf ("%s: sigpause returned\n", __FUNCTION__);
770
771   exit (1);
772 }
773
774
775 static void *
776 tf_sigsuspend (void *arg)
777 {
778   int r = pthread_barrier_wait (&b2);
779   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
780     {
781       printf ("%s: barrier_wait failed\n", __FUNCTION__);
782       exit (1);
783     }
784
785   if (arg != NULL)
786     {
787       r = pthread_barrier_wait (&b2);
788       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
789         {
790           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
791           exit (1);
792         }
793     }
794
795   pthread_cleanup_push (cl, NULL);
796
797   /* Just for fun block all signals.  */
798   sigset_t mask;
799   sigfillset (&mask);
800   sigsuspend (&mask);
801
802   pthread_cleanup_pop (0);
803
804   printf ("%s: sigsuspend returned\n", __FUNCTION__);
805
806   exit (1);
807 }
808
809
810 static void *
811 tf_sigwait (void *arg)
812 {
813   int r = pthread_barrier_wait (&b2);
814   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
815     {
816       printf ("%s: barrier_wait failed\n", __FUNCTION__);
817       exit (1);
818     }
819
820   if (arg != NULL)
821     {
822       r = pthread_barrier_wait (&b2);
823       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
824         {
825           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
826           exit (1);
827         }
828     }
829
830   /* Block SIGUSR1.  */
831   sigset_t mask;
832   sigemptyset (&mask);
833   sigaddset (&mask, SIGUSR1);
834   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
835     {
836       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
837       exit (1);
838     }
839
840   int sig;
841   pthread_cleanup_push (cl, NULL);
842
843   /* Wait for SIGUSR1.  */
844   sigwait (&mask, &sig);
845
846   pthread_cleanup_pop (0);
847
848   printf ("%s: sigwait returned with signal %d\n", __FUNCTION__, sig);
849
850   exit (1);
851 }
852
853
854 static void *
855 tf_sigwaitinfo (void *arg)
856 {
857   int r = pthread_barrier_wait (&b2);
858   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
859     {
860       printf ("%s: barrier_wait failed\n", __FUNCTION__);
861       exit (1);
862     }
863
864   if (arg != NULL)
865     {
866       r = pthread_barrier_wait (&b2);
867       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
868         {
869           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
870           exit (1);
871         }
872     }
873
874   /* Block SIGUSR1.  */
875   sigset_t mask;
876   sigemptyset (&mask);
877   sigaddset (&mask, SIGUSR1);
878   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
879     {
880       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
881       exit (1);
882     }
883
884   siginfo_t info;
885   pthread_cleanup_push (cl, NULL);
886
887   /* Wait for SIGUSR1.  */
888   sigwaitinfo (&mask, &info);
889
890   pthread_cleanup_pop (0);
891
892   printf ("%s: sigwaitinfo returned with signal %d\n", __FUNCTION__,
893           info.si_signo);
894
895   exit (1);
896 }
897
898
899 static void *
900 tf_sigtimedwait (void *arg)
901 {
902   int r = pthread_barrier_wait (&b2);
903   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
904     {
905       printf ("%s: barrier_wait failed\n", __FUNCTION__);
906       exit (1);
907     }
908
909   if (arg != NULL)
910     {
911       r = pthread_barrier_wait (&b2);
912       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
913         {
914           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
915           exit (1);
916         }
917     }
918
919   /* Block SIGUSR1.  */
920   sigset_t mask;
921   sigemptyset (&mask);
922   sigaddset (&mask, SIGUSR1);
923   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
924     {
925       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
926       exit (1);
927     }
928
929   /* Wait for SIGUSR1.  */
930   siginfo_t info;
931   struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
932   pthread_cleanup_push (cl, NULL);
933
934   sigtimedwait (&mask, &info, &ts);
935
936   pthread_cleanup_pop (0);
937
938   printf ("%s: sigtimedwait returned with signal %d\n", __FUNCTION__,
939           info.si_signo);
940
941   exit (1);
942 }
943
944
945 static void *
946 tf_pause (void *arg)
947 {
948   int r = pthread_barrier_wait (&b2);
949   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
950     {
951       printf ("%s: barrier_wait failed\n", __FUNCTION__);
952       exit (1);
953     }
954
955   if (arg != NULL)
956     {
957       r = pthread_barrier_wait (&b2);
958       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
959         {
960           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
961           exit (1);
962         }
963     }
964
965   pthread_cleanup_push (cl, NULL);
966
967   pause ();
968
969   pthread_cleanup_pop (0);
970
971   printf ("%s: pause returned\n", __FUNCTION__);
972
973   exit (1);
974 }
975
976
977 static void *
978 tf_accept (void *arg)
979 {
980   int tfd;
981   struct sockaddr_un sun;
982   /* To test a non-blocking accept call we make the call file by using
983      a datagrame socket.  */
984   int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
985
986   tempfd = socket (AF_UNIX, pf, 0);
987   if (tempfd == -1)
988     {
989       printf ("%s: socket call failed\n", __FUNCTION__);
990       exit (1);
991     }
992
993   int tries = 0;
994   do
995     {
996       if (++tries > 10)
997         {
998           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
999         }
1000
1001       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
1002       tfd = mkstemp(sun.sun_path);
1003       if (tfd < 0)
1004         {
1005           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1006           exit (1);
1007         }
1008       close(tfd);
1009       sun.sun_family = AF_UNIX;
1010     }
1011   while (bind (tempfd, (struct sockaddr *) &sun,
1012                offsetof (struct sockaddr_un, sun_path)
1013                + strlen (sun.sun_path) + 1) != 0);
1014
1015   unlink (sun.sun_path);
1016
1017   listen (tempfd, 5);
1018
1019   socklen_t len = sizeof (sun);
1020
1021   int r = pthread_barrier_wait (&b2);
1022   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1023     {
1024       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1025       exit (1);
1026     }
1027
1028   if (arg != NULL)
1029     {
1030       r = pthread_barrier_wait (&b2);
1031       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1032         {
1033           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1034           exit (1);
1035         }
1036     }
1037
1038   pthread_cleanup_push (cl, NULL);
1039
1040   accept (tempfd, (struct sockaddr *) &sun, &len);
1041
1042   pthread_cleanup_pop (0);
1043
1044   printf ("%s: accept returned\n", __FUNCTION__);
1045
1046   exit (1);
1047 }
1048
1049
1050 static void *
1051 tf_send (void *arg)
1052 {
1053   int tfd;
1054   struct sockaddr_un sun;
1055
1056   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1057   if (tempfd == -1)
1058     {
1059       printf ("%s: first socket call failed\n", __FUNCTION__);
1060       exit (1);
1061     }
1062
1063   int tries = 0;
1064   do
1065     {
1066       if (++tries > 10)
1067         {
1068           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1069         }
1070
1071       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1072       tfd = mkstemp(sun.sun_path);
1073       if (tfd < 0)
1074         {
1075           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1076           exit (1);
1077         }
1078       close(tfd);
1079       sun.sun_family = AF_UNIX;
1080     }
1081   while (bind (tempfd, (struct sockaddr *) &sun,
1082                offsetof (struct sockaddr_un, sun_path)
1083                + strlen (sun.sun_path) + 1) != 0);
1084
1085   listen (tempfd, 5);
1086
1087   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1088   if (tempfd2 == -1)
1089     {
1090       printf ("%s: second socket call failed\n", __FUNCTION__);
1091       exit (1);
1092     }
1093
1094   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1095     {
1096       printf ("%s: connect failed\n", __FUNCTION__);
1097       exit(1);
1098     }
1099
1100   unlink (sun.sun_path);
1101
1102   int r = pthread_barrier_wait (&b2);
1103   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1104     {
1105       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1106       exit (1);
1107     }
1108
1109   if (arg != NULL)
1110     {
1111       r = pthread_barrier_wait (&b2);
1112       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1113         {
1114           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1115           exit (1);
1116         }
1117     }
1118
1119   pthread_cleanup_push (cl, NULL);
1120
1121   /* Very large block, so that the send call blocks.  */
1122   char mem[700000];
1123
1124   send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
1125
1126   pthread_cleanup_pop (0);
1127
1128   printf ("%s: send returned\n", __FUNCTION__);
1129
1130   exit (1);
1131 }
1132
1133
1134 static void *
1135 tf_recv (void *arg)
1136 {
1137   int tfd;
1138   struct sockaddr_un sun;
1139
1140   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1141   if (tempfd == -1)
1142     {
1143       printf ("%s: first socket call failed\n", __FUNCTION__);
1144       exit (1);
1145     }
1146
1147   int tries = 0;
1148   do
1149     {
1150       if (++tries > 10)
1151         {
1152           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1153         }
1154
1155       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
1156       tfd = mkstemp(sun.sun_path);
1157       if (tfd < 0)
1158         {
1159           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1160           exit (1);
1161         }
1162       close(tfd);
1163       sun.sun_family = AF_UNIX;
1164     }
1165   while (bind (tempfd, (struct sockaddr *) &sun,
1166                offsetof (struct sockaddr_un, sun_path)
1167                + strlen (sun.sun_path) + 1) != 0);
1168
1169   listen (tempfd, 5);
1170
1171   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1172   if (tempfd2 == -1)
1173     {
1174       printf ("%s: second socket call failed\n", __FUNCTION__);
1175       exit (1);
1176     }
1177
1178   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
1179     {
1180       printf ("%s: connect failed\n", __FUNCTION__);
1181       exit(1);
1182     }
1183
1184   unlink (sun.sun_path);
1185
1186   int r = pthread_barrier_wait (&b2);
1187   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1188     {
1189       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1190       exit (1);
1191     }
1192
1193   if (arg != NULL)
1194     {
1195       r = pthread_barrier_wait (&b2);
1196       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1197         {
1198           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1199           exit (1);
1200         }
1201     }
1202
1203   pthread_cleanup_push (cl, NULL);
1204
1205   char mem[70];
1206
1207   recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
1208
1209   pthread_cleanup_pop (0);
1210
1211   printf ("%s: recv returned\n", __FUNCTION__);
1212
1213   exit (1);
1214 }
1215
1216
1217 static void *
1218 tf_recvfrom (void *arg)
1219 {
1220   int tfd;
1221   struct sockaddr_un sun;
1222
1223   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1224   if (tempfd == -1)
1225     {
1226       printf ("%s: first socket call failed\n", __FUNCTION__);
1227       exit (1);
1228     }
1229
1230   int tries = 0;
1231   do
1232     {
1233       if (++tries > 10)
1234         {
1235           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1236         }
1237
1238       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
1239       tfd = mkstemp(sun.sun_path);
1240       if (tfd < 0)
1241         {
1242           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1243           exit (1);
1244         }
1245       close(tfd);
1246       sun.sun_family = AF_UNIX;
1247     }
1248   while (bind (tempfd, (struct sockaddr *) &sun,
1249                offsetof (struct sockaddr_un, sun_path)
1250                + strlen (sun.sun_path) + 1) != 0);
1251
1252   tempfname = strdup (sun.sun_path);
1253
1254   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1255   if (tempfd2 == -1)
1256     {
1257       printf ("%s: second socket call failed\n", __FUNCTION__);
1258       exit (1);
1259     }
1260
1261   int r = pthread_barrier_wait (&b2);
1262   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1263     {
1264       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1265       exit (1);
1266     }
1267
1268   if (arg != NULL)
1269     {
1270       r = pthread_barrier_wait (&b2);
1271       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1272         {
1273           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1274           exit (1);
1275         }
1276     }
1277
1278   pthread_cleanup_push (cl, NULL);
1279
1280   char mem[70];
1281   socklen_t len = sizeof (sun);
1282
1283   recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
1284             (struct sockaddr *) &sun, &len);
1285
1286   pthread_cleanup_pop (0);
1287
1288   printf ("%s: recvfrom returned\n", __FUNCTION__);
1289
1290   exit (1);
1291 }
1292
1293
1294 static void *
1295 tf_recvmsg (void *arg)
1296 {
1297   int tfd;
1298   struct sockaddr_un sun;
1299
1300   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1301   if (tempfd == -1)
1302     {
1303       printf ("%s: first socket call failed\n", __FUNCTION__);
1304       exit (1);
1305     }
1306
1307   int tries = 0;
1308   do
1309     {
1310       if (++tries > 10)
1311         {
1312           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1313         }
1314
1315       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
1316       tfd = mkstemp(sun.sun_path);
1317       if (tfd < 0)
1318         {
1319           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1320           exit (1);
1321         }
1322       close(tfd);
1323       sun.sun_family = AF_UNIX;
1324     }
1325   while (bind (tempfd, (struct sockaddr *) &sun,
1326                offsetof (struct sockaddr_un, sun_path)
1327                + strlen (sun.sun_path) + 1) != 0);
1328
1329   tempfname = strdup (sun.sun_path);
1330
1331   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1332   if (tempfd2 == -1)
1333     {
1334       printf ("%s: second socket call failed\n", __FUNCTION__);
1335       exit (1);
1336     }
1337
1338   int r = pthread_barrier_wait (&b2);
1339   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1340     {
1341       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1342       exit (1);
1343     }
1344
1345   if (arg != NULL)
1346     {
1347       r = pthread_barrier_wait (&b2);
1348       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1349         {
1350           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1351           exit (1);
1352         }
1353     }
1354
1355   pthread_cleanup_push (cl, NULL);
1356
1357   char mem[70];
1358   struct iovec iov[1];
1359   iov[0].iov_base = mem;
1360   iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
1361
1362   struct msghdr m;
1363   m.msg_name = &sun;
1364   m.msg_namelen = sizeof (sun);
1365   m.msg_iov = iov;
1366   m.msg_iovlen = 1;
1367   m.msg_control = NULL;
1368   m.msg_controllen = 0;
1369
1370   recvmsg (tempfd2, &m, 0);
1371
1372   pthread_cleanup_pop (0);
1373
1374   printf ("%s: recvmsg returned\n", __FUNCTION__);
1375
1376   exit (1);
1377 }
1378
1379
1380 static void *
1381 tf_open (void *arg)
1382 {
1383   if (arg == NULL)
1384     // XXX If somebody can provide a portable test case in which open()
1385     // blocks we can enable this test to run in both rounds.
1386     abort ();
1387
1388   int r = pthread_barrier_wait (&b2);
1389   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1390     {
1391       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1392       exit (1);
1393     }
1394
1395   r = pthread_barrier_wait (&b2);
1396   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1397     {
1398       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1399       exit (1);
1400     }
1401
1402   pthread_cleanup_push (cl, NULL);
1403
1404   open ("Makefile", O_RDONLY);
1405
1406   pthread_cleanup_pop (0);
1407
1408   printf ("%s: open returned\n", __FUNCTION__);
1409
1410   exit (1);
1411 }
1412
1413
1414 static void *
1415 tf_close (void *arg)
1416 {
1417   if (arg == NULL)
1418     // XXX If somebody can provide a portable test case in which close()
1419     // blocks we can enable this test to run in both rounds.
1420     abort ();
1421
1422   char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
1423   tempfd = mkstemp (fname);
1424   if (tempfd == -1)
1425     {
1426       printf ("%s: mkstemp failed\n", __FUNCTION__);
1427       exit (1);
1428     }
1429   unlink (fname);
1430
1431   int r = pthread_barrier_wait (&b2);
1432   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1433     {
1434       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1435       exit (1);
1436     }
1437
1438   r = pthread_barrier_wait (&b2);
1439   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1440     {
1441       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1442       exit (1);
1443     }
1444
1445   pthread_cleanup_push (cl, NULL);
1446
1447   close (tempfd);
1448
1449   pthread_cleanup_pop (0);
1450
1451   printf ("%s: close returned\n", __FUNCTION__);
1452
1453   exit (1);
1454 }
1455
1456
1457 static void *
1458 tf_pread (void *arg)
1459 {
1460   if (arg == NULL)
1461     // XXX If somebody can provide a portable test case in which pread()
1462     // blocks we can enable this test to run in both rounds.
1463     abort ();
1464
1465   tempfd = open ("Makefile", O_RDONLY);
1466   if (tempfd == -1)
1467     {
1468       printf ("%s: cannot open Makefile\n", __FUNCTION__);
1469       exit (1);
1470     }
1471
1472   int r = pthread_barrier_wait (&b2);
1473   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1474     {
1475       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1476       exit (1);
1477     }
1478
1479   r = pthread_barrier_wait (&b2);
1480   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1481     {
1482       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1483       exit (1);
1484     }
1485
1486   pthread_cleanup_push (cl, NULL);
1487
1488   char mem[10];
1489   pread (tempfd, mem, sizeof (mem), 0);
1490
1491   pthread_cleanup_pop (0);
1492
1493   printf ("%s: pread returned\n", __FUNCTION__);
1494
1495   exit (1);
1496 }
1497
1498
1499 static void *
1500 tf_pwrite (void *arg)
1501 {
1502   if (arg == NULL)
1503     // XXX If somebody can provide a portable test case in which pwrite()
1504     // blocks we can enable this test to run in both rounds.
1505     abort ();
1506
1507   char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
1508   tempfd = mkstemp (fname);
1509   if (tempfd == -1)
1510     {
1511       printf ("%s: mkstemp failed\n", __FUNCTION__);
1512       exit (1);
1513     }
1514   unlink (fname);
1515
1516   int r = pthread_barrier_wait (&b2);
1517   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1518     {
1519       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1520       exit (1);
1521     }
1522
1523   r = pthread_barrier_wait (&b2);
1524   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1525     {
1526       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1527       exit (1);
1528     }
1529
1530   pthread_cleanup_push (cl, NULL);
1531
1532   char mem[10];
1533   pwrite (tempfd, mem, sizeof (mem), 0);
1534
1535   pthread_cleanup_pop (0);
1536
1537   printf ("%s: pwrite returned\n", __FUNCTION__);
1538
1539   exit (1);
1540 }
1541
1542
1543 static void *
1544 tf_fsync (void *arg)
1545 {
1546   if (arg == NULL)
1547     // XXX If somebody can provide a portable test case in which fsync()
1548     // blocks we can enable this test to run in both rounds.
1549     abort ();
1550
1551   tempfd = open ("Makefile", O_RDONLY);
1552   if (tempfd == -1)
1553     {
1554       printf ("%s: cannot open Makefile\n", __FUNCTION__);
1555       exit (1);
1556     }
1557
1558   int r = pthread_barrier_wait (&b2);
1559   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1560     {
1561       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1562       exit (1);
1563     }
1564
1565   r = pthread_barrier_wait (&b2);
1566   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1567     {
1568       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1569       exit (1);
1570     }
1571
1572   pthread_cleanup_push (cl, NULL);
1573
1574   fsync (tempfd);
1575
1576   pthread_cleanup_pop (0);
1577
1578   printf ("%s: fsync returned\n", __FUNCTION__);
1579
1580   exit (1);
1581 }
1582
1583
1584 static void *
1585 tf_fdatasync (void *arg)
1586 {
1587   if (arg == NULL)
1588     // XXX If somebody can provide a portable test case in which fdatasync()
1589     // blocks we can enable this test to run in both rounds.
1590     abort ();
1591
1592   tempfd = open ("Makefile", O_RDONLY);
1593   if (tempfd == -1)
1594     {
1595       printf ("%s: cannot open Makefile\n", __FUNCTION__);
1596       exit (1);
1597     }
1598
1599   int r = pthread_barrier_wait (&b2);
1600   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1601     {
1602       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1603       exit (1);
1604     }
1605
1606   r = pthread_barrier_wait (&b2);
1607   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1608     {
1609       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1610       exit (1);
1611     }
1612
1613   pthread_cleanup_push (cl, NULL);
1614
1615   fdatasync (tempfd);
1616
1617   pthread_cleanup_pop (0);
1618
1619   printf ("%s: fdatasync returned\n", __FUNCTION__);
1620
1621   exit (1);
1622 }
1623
1624
1625 static void *
1626 tf_msync (void *arg)
1627 {
1628   if (arg == NULL)
1629     // XXX If somebody can provide a portable test case in which msync()
1630     // blocks we can enable this test to run in both rounds.
1631     abort ();
1632
1633   tempfd = open ("Makefile", O_RDONLY);
1634   if (tempfd == -1)
1635     {
1636       printf ("%s: cannot open Makefile\n", __FUNCTION__);
1637       exit (1);
1638     }
1639   void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
1640   if (p == MAP_FAILED)
1641     {
1642       printf ("%s: mmap failed\n", __FUNCTION__);
1643       exit (1);
1644     }
1645
1646   int r = pthread_barrier_wait (&b2);
1647   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1648     {
1649       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1650       exit (1);
1651     }
1652
1653   r = pthread_barrier_wait (&b2);
1654   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1655     {
1656       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1657       exit (1);
1658     }
1659
1660   pthread_cleanup_push (cl, NULL);
1661
1662   msync (p, 10, 0);
1663
1664   pthread_cleanup_pop (0);
1665
1666   printf ("%s: msync returned\n", __FUNCTION__);
1667
1668   exit (1);
1669 }
1670
1671
1672 static void *
1673 tf_sendto (void *arg)
1674 {
1675   int tfd;
1676   if (arg == NULL)
1677     // XXX If somebody can provide a portable test case in which sendto()
1678     // blocks we can enable this test to run in both rounds.
1679     abort ();
1680
1681   struct sockaddr_un sun;
1682
1683   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1684   if (tempfd == -1)
1685     {
1686       printf ("%s: first socket call failed\n", __FUNCTION__);
1687       exit (1);
1688     }
1689
1690   int tries = 0;
1691   do
1692     {
1693       if (++tries > 10)
1694         {
1695           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1696         }
1697
1698       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
1699       tfd = mkstemp(sun.sun_path);
1700       if (tfd < 0)
1701         {
1702           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1703           exit (1);
1704         }
1705       close(tfd);
1706       sun.sun_family = AF_UNIX;
1707     }
1708   while (bind (tempfd, (struct sockaddr *) &sun,
1709                offsetof (struct sockaddr_un, sun_path)
1710                + strlen (sun.sun_path) + 1) != 0);
1711   tempfname = strdup (sun.sun_path);
1712
1713   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1714   if (tempfd2 == -1)
1715     {
1716       printf ("%s: second socket call failed\n", __FUNCTION__);
1717       exit (1);
1718     }
1719
1720   int r = pthread_barrier_wait (&b2);
1721   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1722     {
1723       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1724       exit (1);
1725     }
1726
1727   r = pthread_barrier_wait (&b2);
1728   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1729     {
1730       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1731       exit (1);
1732     }
1733
1734   pthread_cleanup_push (cl, NULL);
1735
1736   char mem[1];
1737
1738   sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
1739           (struct sockaddr *) &sun,
1740           offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
1741
1742   pthread_cleanup_pop (0);
1743
1744   printf ("%s: sendto returned\n", __FUNCTION__);
1745
1746   exit (1);
1747 }
1748
1749
1750 static void *
1751 tf_sendmsg (void *arg)
1752 {
1753   int tfd;
1754   if (arg == NULL)
1755     // XXX If somebody can provide a portable test case in which sendmsg()
1756     // blocks we can enable this test to run in both rounds.
1757     abort ();
1758
1759   struct sockaddr_un sun;
1760
1761   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
1762   if (tempfd == -1)
1763     {
1764       printf ("%s: first socket call failed\n", __FUNCTION__);
1765       exit (1);
1766     }
1767
1768   int tries = 0;
1769   do
1770     {
1771       if (++tries > 10)
1772         {
1773           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1774         }
1775
1776       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
1777       tfd = mkstemp(sun.sun_path);
1778       if (tfd < 0)
1779         {
1780           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1781           exit (1);
1782         }
1783       close(tfd);
1784       sun.sun_family = AF_UNIX;
1785     }
1786   while (bind (tempfd, (struct sockaddr *) &sun,
1787                offsetof (struct sockaddr_un, sun_path)
1788                + strlen (sun.sun_path) + 1) != 0);
1789   tempfname = strdup (sun.sun_path);
1790
1791   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
1792   if (tempfd2 == -1)
1793     {
1794       printf ("%s: second socket call failed\n", __FUNCTION__);
1795       exit (1);
1796     }
1797
1798   int r = pthread_barrier_wait (&b2);
1799   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1800     {
1801       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1802       exit (1);
1803     }
1804
1805   r = pthread_barrier_wait (&b2);
1806   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1807     {
1808       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1809       exit (1);
1810     }
1811
1812   pthread_cleanup_push (cl, NULL);
1813
1814   char mem[1];
1815   struct iovec iov[1];
1816   iov[0].iov_base = mem;
1817   iov[0].iov_len = 1;
1818
1819   struct msghdr m;
1820   m.msg_name = &sun;
1821   m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
1822                    + strlen (sun.sun_path) + 1);
1823   m.msg_iov = iov;
1824   m.msg_iovlen = 1;
1825   m.msg_control = NULL;
1826   m.msg_controllen = 0;
1827
1828   sendmsg (tempfd2, &m, 0);
1829
1830   pthread_cleanup_pop (0);
1831
1832   printf ("%s: sendmsg returned\n", __FUNCTION__);
1833
1834   exit (1);
1835 }
1836
1837
1838 static void *
1839 tf_creat (void *arg)
1840 {
1841   if (arg == NULL)
1842     // XXX If somebody can provide a portable test case in which sendmsg()
1843     // blocks we can enable this test to run in both rounds.
1844     abort ();
1845
1846   int r = pthread_barrier_wait (&b2);
1847   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1848     {
1849       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1850       exit (1);
1851     }
1852
1853   r = pthread_barrier_wait (&b2);
1854   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1855     {
1856       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1857       exit (1);
1858     }
1859
1860   pthread_cleanup_push (cl, NULL);
1861
1862   creat ("tmp/tst-cancel-4-should-not-exist", 0666);
1863
1864   pthread_cleanup_pop (0);
1865
1866   printf ("%s: creat returned\n", __FUNCTION__);
1867
1868   exit (1);
1869 }
1870
1871
1872 static void *
1873 tf_connect (void *arg)
1874 {
1875   int tfd;
1876   if (arg == NULL)
1877     // XXX If somebody can provide a portable test case in which connect()
1878     // blocks we can enable this test to run in both rounds.
1879     abort ();
1880
1881   struct sockaddr_un sun;
1882
1883   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
1884   if (tempfd == -1)
1885     {
1886       printf ("%s: first socket call failed\n", __FUNCTION__);
1887       exit (1);
1888     }
1889
1890   int tries = 0;
1891   do
1892     {
1893       if (++tries > 10)
1894         {
1895           printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
1896         }
1897
1898       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
1899       tfd = mkstemp(sun.sun_path);
1900       if (tfd < 0)
1901         {
1902           printf ("%s: cannot generate temp file name\n", __FUNCTION__);
1903           exit (1);
1904         }
1905       close(tfd);
1906       sun.sun_family = AF_UNIX;
1907     }
1908   while (bind (tempfd, (struct sockaddr *) &sun,
1909                offsetof (struct sockaddr_un, sun_path)
1910                + strlen (sun.sun_path) + 1) != 0);
1911   tempfname = strdup (sun.sun_path);
1912
1913   listen (tempfd, 5);
1914
1915   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
1916   if (tempfd2 == -1)
1917     {
1918       printf ("%s: second socket call failed\n", __FUNCTION__);
1919       exit (1);
1920     }
1921
1922   int r = pthread_barrier_wait (&b2);
1923   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1924     {
1925       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1926       exit (1);
1927     }
1928
1929   if (arg != NULL)
1930     {
1931       r = pthread_barrier_wait (&b2);
1932       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1933         {
1934           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1935           exit (1);
1936         }
1937     }
1938
1939   pthread_cleanup_push (cl, NULL);
1940
1941   connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
1942
1943   pthread_cleanup_pop (0);
1944
1945   printf ("%s: connect returned\n", __FUNCTION__);
1946
1947   exit (1);
1948 }
1949
1950
1951 static void *
1952 tf_tcdrain (void *arg)
1953 {
1954   if (arg == NULL)
1955     // XXX If somebody can provide a portable test case in which tcdrain()
1956     // blocks we can enable this test to run in both rounds.
1957     abort ();
1958
1959   int r = pthread_barrier_wait (&b2);
1960   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1961     {
1962       printf ("%s: barrier_wait failed\n", __FUNCTION__);
1963       exit (1);
1964     }
1965
1966   if (arg != NULL)
1967     {
1968       r = pthread_barrier_wait (&b2);
1969       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
1970         {
1971           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
1972           exit (1);
1973         }
1974     }
1975
1976   pthread_cleanup_push (cl, NULL);
1977
1978   /* Regardless of stderr being a terminal, the tcdrain call should be
1979      canceled.  */
1980   tcdrain (STDERR_FILENO);
1981
1982   pthread_cleanup_pop (0);
1983
1984   printf ("%s: tcdrain returned\n", __FUNCTION__);
1985
1986   exit (1);
1987 }
1988
1989
1990 static void *
1991 tf_msgrcv (void *arg)
1992 {
1993   tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
1994   if (tempmsg == -1)
1995     {
1996       printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
1997       exit (1);
1998     }
1999
2000   int r = pthread_barrier_wait (&b2);
2001   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2002     {
2003       printf ("%s: barrier_wait failed\n", __FUNCTION__);
2004       exit (1);
2005     }
2006
2007   if (arg != NULL)
2008     {
2009       r = pthread_barrier_wait (&b2);
2010       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2011         {
2012           printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
2013           exit (1);
2014         }
2015     }
2016
2017   ssize_t s;
2018
2019   pthread_cleanup_push (cl, NULL);
2020
2021   struct
2022   {
2023     long int type;
2024     char mem[10];
2025   } m;
2026   int randnr;
2027   /* We need a positive random number.  */
2028   do
2029     randnr = random () % 64000;
2030   while (randnr <= 0);
2031   do
2032     {
2033       errno = 0;
2034       s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
2035     }
2036   while (errno == EIDRM || errno == EINTR);
2037
2038   pthread_cleanup_pop (0);
2039
2040   printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);
2041
2042   msgctl (tempmsg, IPC_RMID, NULL);
2043
2044   exit (1);
2045 }
2046
2047
2048 static void *
2049 tf_msgsnd (void *arg)
2050 {
2051   if (arg == NULL)
2052     // XXX If somebody can provide a portable test case in which msgsnd()
2053     // blocks we can enable this test to run in both rounds.
2054     abort ();
2055
2056   tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
2057   if (tempmsg == -1)
2058     {
2059       printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
2060       exit (1);
2061     }
2062
2063   int r = pthread_barrier_wait (&b2);
2064   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2065     {
2066       printf ("%s: barrier_wait failed\n", __FUNCTION__);
2067       exit (1);
2068     }
2069
2070   r = pthread_barrier_wait (&b2);
2071   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2072     {
2073       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
2074       exit (1);
2075     }
2076
2077   pthread_cleanup_push (cl, NULL);
2078
2079   struct
2080   {
2081     long int type;
2082     char mem[1];
2083   } m;
2084   /* We need a positive random number.  */
2085   do
2086     m.type = random () % 64000;
2087   while (m.type <= 0);
2088   msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
2089
2090   pthread_cleanup_pop (0);
2091
2092   printf ("%s: msgsnd returned\n", __FUNCTION__);
2093
2094   msgctl (tempmsg, IPC_RMID, NULL);
2095
2096   exit (1);
2097 }
2098
2099
2100 static struct
2101 {
2102   const char *name;
2103   void *(*tf) (void *);
2104   int nb;
2105   int only_early;
2106 } tests[] =
2107 {
2108 #define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early }
2109   ADD_TEST (read, 2, 0),
2110   ADD_TEST (readv, 2, 0),
2111   ADD_TEST (select, 2, 0),
2112   ADD_TEST (pselect, 2, 0),
2113   ADD_TEST (poll, 2, 0),
2114   ADD_TEST (ppoll, 2, 0),
2115   ADD_TEST (write, 2, 0),
2116   ADD_TEST (writev, 2, 0),
2117   ADD_TEST (sleep, 2, 0),
2118   ADD_TEST (usleep, 2, 0),
2119   ADD_TEST (nanosleep, 2, 0),
2120   ADD_TEST (wait, 2, 0),
2121   ADD_TEST (waitid, 2, 0),
2122   ADD_TEST (waitpid, 2, 0),
2123   ADD_TEST (sigpause, 2, 0),
2124   ADD_TEST (sigsuspend, 2, 0),
2125   ADD_TEST (sigwait, 2, 0),
2126   ADD_TEST (sigwaitinfo, 2, 0),
2127   ADD_TEST (sigtimedwait, 2, 0),
2128   ADD_TEST (pause, 2, 0),
2129   ADD_TEST (accept, 2, 0),
2130   ADD_TEST (send, 2, 0),
2131   ADD_TEST (recv, 2, 0),
2132   ADD_TEST (recvfrom, 2, 0),
2133   ADD_TEST (recvmsg, 2, 0),
2134   ADD_TEST (open, 2, 1),
2135   ADD_TEST (close, 2, 1),
2136   ADD_TEST (pread, 2, 1),
2137   ADD_TEST (pwrite, 2, 1),
2138   ADD_TEST (fsync, 2, 1),
2139   ADD_TEST (fdatasync, 2, 1),
2140   ADD_TEST (msync, 2, 1),
2141   ADD_TEST (sendto, 2, 1),
2142   ADD_TEST (sendmsg, 2, 1),
2143   ADD_TEST (creat, 2, 1),
2144   ADD_TEST (connect, 2, 1),
2145   ADD_TEST (tcdrain, 2, 1),
2146   ADD_TEST (msgrcv, 2, 0),
2147   ADD_TEST (msgsnd, 2, 1),
2148 };
2149 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
2150
2151
2152 static int
2153 do_test (void)
2154 {
2155   int val;
2156   socklen_t len;
2157
2158   if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
2159     {
2160       perror ("socketpair");
2161       exit (1);
2162     }
2163
2164   val = 1;
2165   len = sizeof(val);
2166   setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2167   if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
2168     {
2169       perror ("getsockopt");
2170       exit (1);
2171     }
2172   if (val >= WRITE_BUFFER_SIZE)
2173     {
2174       puts ("minimum write buffer size too large");
2175       exit (1);
2176     }
2177   setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
2178
2179   int result = 0;
2180   size_t cnt;
2181   for (cnt = 0; cnt < ntest_tf; ++cnt)
2182     {
2183       if (tests[cnt].only_early)
2184         continue;
2185
2186       if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2187         {
2188           puts ("b2 init failed");
2189           exit (1);
2190         }
2191
2192       /* Reset the counter for the cleanup handler.  */
2193       cl_called = 0;
2194
2195       pthread_t th;
2196       if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
2197         {
2198           printf ("create for '%s' test failed\n", tests[cnt].name);
2199           result = 1;
2200           continue;
2201         }
2202
2203       int r = pthread_barrier_wait (&b2);
2204       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2205         {
2206           printf ("%s: barrier_wait failed\n", __FUNCTION__);
2207           result = 1;
2208           continue;
2209         }
2210
2211       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
2212       while (nanosleep (&ts, &ts) != 0)
2213         continue;
2214
2215       if (pthread_cancel (th) != 0)
2216         {
2217           printf ("cancel for '%s' failed\n", tests[cnt].name);
2218           result = 1;
2219           continue;
2220         }
2221
2222       void *status;
2223       if (pthread_join (th, &status) != 0)
2224         {
2225           printf ("join for '%s' failed\n", tests[cnt].name);
2226           result = 1;
2227           continue;
2228         }
2229       if (status != PTHREAD_CANCELED)
2230         {
2231           printf ("thread for '%s' not canceled\n", tests[cnt].name);
2232           result = 1;
2233           continue;
2234         }
2235
2236       if (pthread_barrier_destroy (&b2) != 0)
2237         {
2238           puts ("barrier_destroy failed");
2239           result = 1;
2240           continue;
2241         }
2242
2243       if (cl_called == 0)
2244         {
2245           printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2246           result = 1;
2247           continue;
2248         }
2249       if (cl_called > 1)
2250         {
2251           printf ("cleanup handler called more than once for '%s'\n",
2252                   tests[cnt].name);
2253           result = 1;
2254           continue;
2255         }
2256
2257       printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);
2258
2259       if (tempfd != -1)
2260         {
2261           close (tempfd);
2262           tempfd = -1;
2263         }
2264       if (tempfd2 != -1)
2265         {
2266           close (tempfd2);
2267           tempfd2 = -1;
2268         }
2269       if (tempfname != NULL)
2270         {
2271           unlink (tempfname);
2272           free (tempfname);
2273           tempfname = NULL;
2274         }
2275       if (tempmsg != -1)
2276         {
2277           msgctl (tempmsg, IPC_RMID, NULL);
2278           tempmsg = -1;
2279         }
2280     }
2281
2282   for (cnt = 0; cnt < ntest_tf; ++cnt)
2283     {
2284       if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
2285         {
2286           puts ("b2 init failed");
2287           exit (1);
2288         }
2289
2290       /* Reset the counter for the cleanup handler.  */
2291       cl_called = 0;
2292
2293       pthread_t th;
2294       if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
2295         {
2296           printf ("create for '%s' test failed\n", tests[cnt].name);
2297           result = 1;
2298           continue;
2299         }
2300
2301       int r = pthread_barrier_wait (&b2);
2302       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2303         {
2304           printf ("%s: barrier_wait failed\n", __FUNCTION__);
2305           result = 1;
2306           continue;
2307         }
2308
2309       if (pthread_cancel (th) != 0)
2310         {
2311           printf ("cancel for '%s' failed\n", tests[cnt].name);
2312           result = 1;
2313           continue;
2314         }
2315
2316       r = pthread_barrier_wait (&b2);
2317       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
2318         {
2319           printf ("%s: barrier_wait failed\n", __FUNCTION__);
2320           result = 1;
2321           continue;
2322         }
2323
2324       void *status;
2325       if (pthread_join (th, &status) != 0)
2326         {
2327           printf ("join for '%s' failed\n", tests[cnt].name);
2328           result = 1;
2329           continue;
2330         }
2331       if (status != PTHREAD_CANCELED)
2332         {
2333           printf ("thread for '%s' not canceled\n", tests[cnt].name);
2334           result = 1;
2335           continue;
2336         }
2337
2338       if (pthread_barrier_destroy (&b2) != 0)
2339         {
2340           puts ("barrier_destroy failed");
2341           result = 1;
2342           continue;
2343         }
2344
2345       if (cl_called == 0)
2346         {
2347           printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
2348           result = 1;
2349           continue;
2350         }
2351       if (cl_called > 1)
2352         {
2353           printf ("cleanup handler called more than once for '%s'\n",
2354                   tests[cnt].name);
2355           result = 1;
2356           continue;
2357         }
2358
2359       printf ("early cancel test of '%s' successful\n", tests[cnt].name);
2360
2361       if (tempfd != -1)
2362         {
2363           close (tempfd);
2364           tempfd = -1;
2365         }
2366       if (tempfd2 != -1)
2367         {
2368           close (tempfd2);
2369           tempfd2 = -1;
2370         }
2371       if (tempfname != NULL)
2372         {
2373           unlink (tempfname);
2374           free (tempfname);
2375           tempfname = NULL;
2376         }
2377       if (tempmsg != -1)
2378         {
2379           msgctl (tempmsg, IPC_RMID, NULL);
2380           tempmsg = -1;
2381         }
2382     }
2383
2384   return result;
2385 }
2386
2387 #define TIMEOUT 60
2388 #define TEST_FUNCTION do_test ()
2389 #include "../test-skeleton.c"