Back to index

glibc  2.9
tst-cancel4.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 /* NOTE: this tests functionality beyond POSIX.  POSIX does not allow
00021    exit to be called more than once.  */
00022 
00023 #include <errno.h>
00024 #include <fcntl.h>
00025 #include <limits.h>
00026 #include <pthread.h>
00027 #include <stddef.h>
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <termios.h>
00032 #include <unistd.h>
00033 #include <sys/mman.h>
00034 #include <sys/msg.h>
00035 #include <sys/poll.h>
00036 #include <sys/select.h>
00037 #include <sys/socket.h>
00038 #include <sys/uio.h>
00039 #include <sys/un.h>
00040 #include <sys/wait.h>
00041 
00042 #include "pthreadP.h"
00043 
00044 
00045 /* Since STREAMS are not supported in the standard Linux kernel and
00046    there we don't advertise STREAMS as supported is no need to test
00047    the STREAMS related functions.  This affects
00048      getmsg()              getpmsg()          putmsg()
00049      putpmsg()
00050 
00051    lockf() and fcntl() are tested in tst-cancel16.
00052 
00053    pthread_join() is tested in tst-join5.
00054 
00055    pthread_testcancel()'s only purpose is to allow cancellation.  This
00056    is tested in several places.
00057 
00058    sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests.
00059 
00060    mq_send(), mq_timedsend(), mq_receive() and mq_timedreceive() are checked
00061    in tst-mqueue8{,x} tests.
00062 
00063    aio_suspend() is tested in tst-cancel17.
00064 
00065    clock_nanosleep() is tested in tst-cancel18.
00066 */
00067 
00068 /* Pipe descriptors.  */
00069 static int fds[2];
00070 
00071 /* Temporary file descriptor, to be closed after each round.  */
00072 static int tempfd = -1;
00073 static int tempfd2 = -1;
00074 /* Name of temporary file to be removed after each round.  */
00075 static char *tempfname;
00076 /* Temporary message queue.  */
00077 static int tempmsg = -1;
00078 
00079 /* Often used barrier for two threads.  */
00080 static pthread_barrier_t b2;
00081 
00082 
00083 #ifndef IPC_ADDVAL
00084 # define IPC_ADDVAL 0
00085 #endif
00086 
00087 #define WRITE_BUFFER_SIZE 4096
00088 
00089 /* Cleanup handling test.  */
00090 static int cl_called;
00091 
00092 static void
00093 cl (void *arg)
00094 {
00095   ++cl_called;
00096 }
00097 
00098 
00099 
00100 static void *
00101 tf_read  (void *arg)
00102 {
00103   int fd;
00104   int r;
00105 
00106   if (arg == NULL)
00107     fd = fds[0];
00108   else
00109     {
00110       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
00111       tempfd = fd = mkstemp (fname);
00112       if (fd == -1)
00113        printf ("%s: mkstemp failed\n", __FUNCTION__);
00114       unlink (fname);
00115 
00116       r = pthread_barrier_wait (&b2);
00117       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00118        {
00119          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00120          exit (1);
00121        }
00122     }
00123 
00124   r = pthread_barrier_wait (&b2);
00125   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00126     {
00127       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00128       exit (1);
00129     }
00130 
00131   ssize_t s;
00132   pthread_cleanup_push (cl, NULL);
00133 
00134   char buf[100];
00135   s = read (fd, buf, sizeof (buf));
00136 
00137   pthread_cleanup_pop (0);
00138 
00139   printf ("%s: read returns with %zd\n", __FUNCTION__, s);
00140 
00141   exit (1);
00142 }
00143 
00144 
00145 static void *
00146 tf_readv  (void *arg)
00147 {
00148   int fd;
00149   int r;
00150 
00151   if (arg == NULL)
00152     fd = fds[0];
00153   else
00154     {
00155       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
00156       tempfd = fd = mkstemp (fname);
00157       if (fd == -1)
00158        printf ("%s: mkstemp failed\n", __FUNCTION__);
00159       unlink (fname);
00160 
00161       r = pthread_barrier_wait (&b2);
00162       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00163        {
00164          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00165          exit (1);
00166        }
00167     }
00168 
00169   r = pthread_barrier_wait (&b2);
00170   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00171     {
00172       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00173       exit (1);
00174     }
00175 
00176   ssize_t s;
00177   pthread_cleanup_push (cl, NULL);
00178 
00179   char buf[100];
00180   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
00181   s = readv (fd, iov, 1);
00182 
00183   pthread_cleanup_pop (0);
00184 
00185   printf ("%s: readv returns with %zd\n", __FUNCTION__, s);
00186 
00187   exit (1);
00188 }
00189 
00190 
00191 static void *
00192 tf_write  (void *arg)
00193 {
00194   int fd;
00195   int r;
00196 
00197   if (arg == NULL)
00198     fd = fds[1];
00199   else
00200     {
00201       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
00202       tempfd = fd = mkstemp (fname);
00203       if (fd == -1)
00204        printf ("%s: mkstemp failed\n", __FUNCTION__);
00205       unlink (fname);
00206 
00207       r = pthread_barrier_wait (&b2);
00208       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00209        {
00210          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00211          exit (1);
00212        }
00213     }
00214 
00215   r = pthread_barrier_wait (&b2);
00216   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00217     {
00218       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00219       exit (1);
00220     }
00221 
00222   ssize_t s;
00223   pthread_cleanup_push (cl, NULL);
00224 
00225   char buf[WRITE_BUFFER_SIZE];
00226   memset (buf, '\0', sizeof (buf));
00227   s = write (fd, buf, sizeof (buf));
00228 
00229   pthread_cleanup_pop (0);
00230 
00231   printf ("%s: write returns with %zd\n", __FUNCTION__, s);
00232 
00233   exit (1);
00234 }
00235 
00236 
00237 static void *
00238 tf_writev  (void *arg)
00239 {
00240   int fd;
00241   int r;
00242 
00243   if (arg == NULL)
00244     fd = fds[1];
00245   else
00246     {
00247       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
00248       tempfd = fd = mkstemp (fname);
00249       if (fd == -1)
00250        printf ("%s: mkstemp failed\n", __FUNCTION__);
00251       unlink (fname);
00252 
00253       r = pthread_barrier_wait (&b2);
00254       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00255        {
00256          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00257          exit (1);
00258        }
00259     }
00260 
00261   r = pthread_barrier_wait (&b2);
00262   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00263     {
00264       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00265       exit (1);
00266     }
00267 
00268   ssize_t s;
00269   pthread_cleanup_push (cl, NULL);
00270 
00271   char buf[WRITE_BUFFER_SIZE];
00272   memset (buf, '\0', sizeof (buf));
00273   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
00274   s = writev (fd, iov, 1);
00275 
00276   pthread_cleanup_pop (0);
00277 
00278   printf ("%s: writev returns with %zd\n", __FUNCTION__, s);
00279 
00280   exit (1);
00281 }
00282 
00283 
00284 static void *
00285 tf_sleep (void *arg)
00286 {
00287   int r = pthread_barrier_wait (&b2);
00288   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00289     {
00290       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00291       exit (1);
00292     }
00293 
00294   if (arg != NULL)
00295     {
00296       r = pthread_barrier_wait (&b2);
00297       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00298        {
00299          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00300          exit (1);
00301        }
00302     }
00303 
00304   pthread_cleanup_push (cl, NULL);
00305 
00306   sleep (arg == NULL ? 1000000 : 0);
00307 
00308   pthread_cleanup_pop (0);
00309 
00310   printf ("%s: sleep returns\n", __FUNCTION__);
00311 
00312   exit (1);
00313 }
00314 
00315 
00316 static void *
00317 tf_usleep (void *arg)
00318 {
00319   int r = pthread_barrier_wait (&b2);
00320   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00321     {
00322       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00323       exit (1);
00324     }
00325 
00326   if (arg != NULL)
00327     {
00328       r = pthread_barrier_wait (&b2);
00329       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00330        {
00331          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
00332          exit (1);
00333        }
00334     }
00335 
00336   pthread_cleanup_push (cl, NULL);
00337 
00338   usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0);
00339 
00340   pthread_cleanup_pop (0);
00341 
00342   printf ("%s: usleep returns\n", __FUNCTION__);
00343 
00344   exit (1);
00345 }
00346 
00347 
00348 static void *
00349 tf_nanosleep (void *arg)
00350 {
00351   int r = pthread_barrier_wait (&b2);
00352   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00353     {
00354       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00355       exit (1);
00356     }
00357 
00358   if (arg != NULL)
00359     {
00360       r = pthread_barrier_wait (&b2);
00361       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00362        {
00363          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00364          exit (1);
00365        }
00366     }
00367 
00368   pthread_cleanup_push (cl, NULL);
00369 
00370   struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 };
00371   TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
00372 
00373   pthread_cleanup_pop (0);
00374 
00375   printf ("%s: nanosleep returns\n", __FUNCTION__);
00376 
00377   exit (1);
00378 }
00379 
00380 
00381 static void *
00382 tf_select (void *arg)
00383 {
00384   int fd;
00385   int r;
00386 
00387   if (arg == NULL)
00388     fd = fds[0];
00389   else
00390     {
00391       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
00392       tempfd = fd = mkstemp (fname);
00393       if (fd == -1)
00394        printf ("%s: mkstemp failed\n", __FUNCTION__);
00395       unlink (fname);
00396 
00397       r = pthread_barrier_wait (&b2);
00398       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00399        {
00400          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00401          exit (1);
00402        }
00403     }
00404 
00405   r = pthread_barrier_wait (&b2);
00406   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00407     {
00408       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00409       exit (1);
00410     }
00411 
00412   fd_set rfs;
00413   FD_ZERO (&rfs);
00414   FD_SET (fd, &rfs);
00415 
00416   int s;
00417   pthread_cleanup_push (cl, NULL);
00418 
00419   s = select (fd + 1, &rfs, NULL, NULL, NULL);
00420 
00421   pthread_cleanup_pop (0);
00422 
00423   printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s,
00424          strerror (errno));
00425 
00426   exit (1);
00427 }
00428 
00429 
00430 static void *
00431 tf_pselect (void *arg)
00432 {
00433   int fd;
00434   int r;
00435 
00436   if (arg == NULL)
00437     fd = fds[0];
00438   else
00439     {
00440       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
00441       tempfd = fd = mkstemp (fname);
00442       if (fd == -1)
00443        printf ("%s: mkstemp failed\n", __FUNCTION__);
00444       unlink (fname);
00445 
00446       r = pthread_barrier_wait (&b2);
00447       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00448        {
00449          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00450          exit (1);
00451        }
00452     }
00453 
00454   r = pthread_barrier_wait (&b2);
00455   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00456     {
00457       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00458       exit (1);
00459     }
00460 
00461   fd_set rfs;
00462   FD_ZERO (&rfs);
00463   FD_SET (fd, &rfs);
00464 
00465   int s;
00466   pthread_cleanup_push (cl, NULL);
00467 
00468   s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL);
00469 
00470   pthread_cleanup_pop (0);
00471 
00472   printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s,
00473          strerror (errno));
00474 
00475   exit (1);
00476 }
00477 
00478 
00479 static void *
00480 tf_poll (void *arg)
00481 {
00482   int fd;
00483   int r;
00484 
00485   if (arg == NULL)
00486     fd = fds[0];
00487   else
00488     {
00489       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
00490       tempfd = fd = mkstemp (fname);
00491       if (fd == -1)
00492        printf ("%s: mkstemp failed\n", __FUNCTION__);
00493       unlink (fname);
00494 
00495       r = pthread_barrier_wait (&b2);
00496       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00497        {
00498          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00499          exit (1);
00500        }
00501     }
00502 
00503   r = pthread_barrier_wait (&b2);
00504   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00505     {
00506       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00507       exit (1);
00508     }
00509 
00510   struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
00511 
00512   int s;
00513   pthread_cleanup_push (cl, NULL);
00514 
00515   s = poll (rfs, 1, -1);
00516 
00517   pthread_cleanup_pop (0);
00518 
00519   printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s,
00520          strerror (errno));
00521 
00522   exit (1);
00523 }
00524 
00525 
00526 static void *
00527 tf_ppoll (void *arg)
00528 {
00529   int fd;
00530   int r;
00531 
00532   if (arg == NULL)
00533     fd = fds[0];
00534   else
00535     {
00536       char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
00537       tempfd = fd = mkstemp (fname);
00538       if (fd == -1)
00539        printf ("%s: mkstemp failed\n", __FUNCTION__);
00540       unlink (fname);
00541 
00542       r = pthread_barrier_wait (&b2);
00543       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00544        {
00545          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00546          exit (1);
00547        }
00548     }
00549 
00550   r = pthread_barrier_wait (&b2);
00551   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00552     {
00553       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00554       exit (1);
00555     }
00556 
00557   struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
00558 
00559   int s;
00560   pthread_cleanup_push (cl, NULL);
00561 
00562   s = ppoll (rfs, 1, NULL, NULL);
00563 
00564   pthread_cleanup_pop (0);
00565 
00566   printf ("%s: ppoll returns with %d (%s)\n", __FUNCTION__, s,
00567          strerror (errno));
00568 
00569   exit (1);
00570 }
00571 
00572 
00573 static void *
00574 tf_wait (void *arg)
00575 {
00576   pid_t pid = fork ();
00577   if (pid == -1)
00578     {
00579       puts ("fork failed");
00580       exit (1);
00581     }
00582 
00583   if (pid == 0)
00584     {
00585       /* Make the program disappear after a while.  */
00586       if (arg == NULL)
00587        sleep (10);
00588       exit (0);
00589     }
00590 
00591   int r;
00592   if (arg != NULL)
00593     {
00594       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
00595       while (nanosleep (&ts, &ts) != 0)
00596        continue;
00597 
00598       r = pthread_barrier_wait (&b2);
00599       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00600        {
00601          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00602          exit (1);
00603        }
00604     }
00605 
00606   r = pthread_barrier_wait (&b2);
00607   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00608     {
00609       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00610       exit (1);
00611     }
00612 
00613   int s;
00614   pthread_cleanup_push (cl, NULL);
00615 
00616   s = wait (NULL);
00617 
00618   pthread_cleanup_pop (0);
00619 
00620   printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
00621          strerror (errno));
00622 
00623   exit (1);
00624 }
00625 
00626 
00627 static void *
00628 tf_waitpid (void *arg)
00629 {
00630 
00631   pid_t pid = fork ();
00632   if (pid == -1)
00633     {
00634       puts ("fork failed");
00635       exit (1);
00636     }
00637 
00638   if (pid == 0)
00639     {
00640       /* Make the program disappear after a while.  */
00641       if (arg == NULL)
00642        sleep (10);
00643       exit (0);
00644     }
00645 
00646   int r;
00647   if (arg != NULL)
00648     {
00649       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
00650       while (nanosleep (&ts, &ts) != 0)
00651        continue;
00652 
00653       r = pthread_barrier_wait (&b2);
00654       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00655        {
00656          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00657          exit (1);
00658        }
00659     }
00660 
00661   r = pthread_barrier_wait (&b2);
00662   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00663     {
00664       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00665       exit (1);
00666     }
00667 
00668   int s;
00669  pthread_cleanup_push (cl, NULL);
00670 
00671   s = waitpid (-1, NULL, 0);
00672 
00673   pthread_cleanup_pop (0);
00674 
00675   printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
00676          strerror (errno));
00677 
00678   exit (1);
00679 }
00680 
00681 
00682 static void *
00683 tf_waitid (void *arg)
00684 {
00685   pid_t pid = fork ();
00686   if (pid == -1)
00687     {
00688       puts ("fork failed");
00689       exit (1);
00690     }
00691 
00692   if (pid == 0)
00693     {
00694       /* Make the program disappear after a while.  */
00695       if (arg == NULL)
00696        sleep (10);
00697       exit (0);
00698     }
00699 
00700   int r;
00701   if (arg != NULL)
00702     {
00703       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
00704       while (nanosleep (&ts, &ts) != 0)
00705        continue;
00706 
00707       r = pthread_barrier_wait (&b2);
00708       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00709        {
00710          printf ("%s: barrier_wait failed\n", __FUNCTION__);
00711          exit (1);
00712        }
00713     }
00714 
00715   r = pthread_barrier_wait (&b2);
00716   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00717     {
00718       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00719       exit (1);
00720     }
00721 
00722   int s;
00723   pthread_cleanup_push (cl, NULL);
00724 
00725 #ifndef WEXITED
00726 # define WEXITED 0
00727 #endif
00728   siginfo_t si;
00729   s = waitid (P_PID, pid, &si, WEXITED);
00730 
00731   pthread_cleanup_pop (0);
00732 
00733   printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
00734          strerror (errno));
00735 
00736   exit (1);
00737 }
00738 
00739 
00740 static void *
00741 tf_sigpause (void *arg)
00742 {
00743   int r = pthread_barrier_wait (&b2);
00744   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00745     {
00746       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00747       exit (1);
00748     }
00749 
00750   if (arg != NULL)
00751     {
00752       r = pthread_barrier_wait (&b2);
00753       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00754        {
00755          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
00756          exit (1);
00757        }
00758     }
00759 
00760   pthread_cleanup_push (cl, NULL);
00761 
00762   /* Just for fun block the cancellation signal.  We need to use
00763      __xpg_sigpause since otherwise we will get the BSD version.  */
00764   __xpg_sigpause (SIGCANCEL);
00765 
00766   pthread_cleanup_pop (0);
00767 
00768   printf ("%s: sigpause returned\n", __FUNCTION__);
00769 
00770   exit (1);
00771 }
00772 
00773 
00774 static void *
00775 tf_sigsuspend (void *arg)
00776 {
00777   int r = pthread_barrier_wait (&b2);
00778   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00779     {
00780       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00781       exit (1);
00782     }
00783 
00784   if (arg != NULL)
00785     {
00786       r = pthread_barrier_wait (&b2);
00787       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00788        {
00789          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
00790          exit (1);
00791        }
00792     }
00793 
00794   pthread_cleanup_push (cl, NULL);
00795 
00796   /* Just for fun block all signals.  */
00797   sigset_t mask;
00798   sigfillset (&mask);
00799   sigsuspend (&mask);
00800 
00801   pthread_cleanup_pop (0);
00802 
00803   printf ("%s: sigsuspend returned\n", __FUNCTION__);
00804 
00805   exit (1);
00806 }
00807 
00808 
00809 static void *
00810 tf_sigwait (void *arg)
00811 {
00812   int r = pthread_barrier_wait (&b2);
00813   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00814     {
00815       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00816       exit (1);
00817     }
00818 
00819   if (arg != NULL)
00820     {
00821       r = pthread_barrier_wait (&b2);
00822       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00823        {
00824          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
00825          exit (1);
00826        }
00827     }
00828 
00829   /* Block SIGUSR1.  */
00830   sigset_t mask;
00831   sigemptyset (&mask);
00832   sigaddset (&mask, SIGUSR1);
00833   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
00834     {
00835       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
00836       exit (1);
00837     }
00838 
00839   int sig;
00840   pthread_cleanup_push (cl, NULL);
00841 
00842   /* Wait for SIGUSR1.  */
00843   sigwait (&mask, &sig);
00844 
00845   pthread_cleanup_pop (0);
00846 
00847   printf ("%s: sigwait returned with signal %d\n", __FUNCTION__, sig);
00848 
00849   exit (1);
00850 }
00851 
00852 
00853 static void *
00854 tf_sigwaitinfo (void *arg)
00855 {
00856   int r = pthread_barrier_wait (&b2);
00857   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00858     {
00859       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00860       exit (1);
00861     }
00862 
00863   if (arg != NULL)
00864     {
00865       r = pthread_barrier_wait (&b2);
00866       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00867        {
00868          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
00869          exit (1);
00870        }
00871     }
00872 
00873   /* Block SIGUSR1.  */
00874   sigset_t mask;
00875   sigemptyset (&mask);
00876   sigaddset (&mask, SIGUSR1);
00877   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
00878     {
00879       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
00880       exit (1);
00881     }
00882 
00883   siginfo_t info;
00884   pthread_cleanup_push (cl, NULL);
00885 
00886   /* Wait for SIGUSR1.  */
00887   sigwaitinfo (&mask, &info);
00888 
00889   pthread_cleanup_pop (0);
00890 
00891   printf ("%s: sigwaitinfo returned with signal %d\n", __FUNCTION__,
00892          info.si_signo);
00893 
00894   exit (1);
00895 }
00896 
00897 
00898 static void *
00899 tf_sigtimedwait (void *arg)
00900 {
00901   int r = pthread_barrier_wait (&b2);
00902   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00903     {
00904       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00905       exit (1);
00906     }
00907 
00908   if (arg != NULL)
00909     {
00910       r = pthread_barrier_wait (&b2);
00911       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00912        {
00913          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
00914          exit (1);
00915        }
00916     }
00917 
00918   /* Block SIGUSR1.  */
00919   sigset_t mask;
00920   sigemptyset (&mask);
00921   sigaddset (&mask, SIGUSR1);
00922   if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
00923     {
00924       printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
00925       exit (1);
00926     }
00927 
00928   /* Wait for SIGUSR1.  */
00929   siginfo_t info;
00930   struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
00931   pthread_cleanup_push (cl, NULL);
00932 
00933   sigtimedwait (&mask, &info, &ts);
00934 
00935   pthread_cleanup_pop (0);
00936 
00937   printf ("%s: sigtimedwait returned with signal %d\n", __FUNCTION__,
00938          info.si_signo);
00939 
00940   exit (1);
00941 }
00942 
00943 
00944 static void *
00945 tf_pause (void *arg)
00946 {
00947   int r = pthread_barrier_wait (&b2);
00948   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00949     {
00950       printf ("%s: barrier_wait failed\n", __FUNCTION__);
00951       exit (1);
00952     }
00953 
00954   if (arg != NULL)
00955     {
00956       r = pthread_barrier_wait (&b2);
00957       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
00958        {
00959          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
00960          exit (1);
00961        }
00962     }
00963 
00964   pthread_cleanup_push (cl, NULL);
00965 
00966   pause ();
00967 
00968   pthread_cleanup_pop (0);
00969 
00970   printf ("%s: pause returned\n", __FUNCTION__);
00971 
00972   exit (1);
00973 }
00974 
00975 
00976 static void *
00977 tf_accept (void *arg)
00978 {
00979   struct sockaddr_un sun;
00980   /* To test a non-blocking accept call we make the call file by using
00981      a datagrame socket.  */
00982   int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
00983 
00984   tempfd = socket (AF_UNIX, pf, 0);
00985   if (tempfd == -1)
00986     {
00987       printf ("%s: socket call failed\n", __FUNCTION__);
00988       exit (1);
00989     }
00990 
00991   int tries = 0;
00992   do
00993     {
00994       if (++tries > 10)
00995        {
00996          printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
00997        }
00998 
00999       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
01000       if (mktemp (sun.sun_path) == NULL)
01001        {
01002          printf ("%s: cannot generate temp file name\n", __FUNCTION__);
01003          exit (1);
01004        }
01005 
01006       sun.sun_family = AF_UNIX;
01007     }
01008   while (bind (tempfd, (struct sockaddr *) &sun,
01009               offsetof (struct sockaddr_un, sun_path)
01010               + strlen (sun.sun_path) + 1) != 0);
01011 
01012   unlink (sun.sun_path);
01013 
01014   listen (tempfd, 5);
01015 
01016   socklen_t len = sizeof (sun);
01017 
01018   int r = pthread_barrier_wait (&b2);
01019   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01020     {
01021       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01022       exit (1);
01023     }
01024 
01025   if (arg != NULL)
01026     {
01027       r = pthread_barrier_wait (&b2);
01028       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01029        {
01030          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01031          exit (1);
01032        }
01033     }
01034 
01035   pthread_cleanup_push (cl, NULL);
01036 
01037   accept (tempfd, (struct sockaddr *) &sun, &len);
01038 
01039   pthread_cleanup_pop (0);
01040 
01041   printf ("%s: accept returned\n", __FUNCTION__);
01042 
01043   exit (1);
01044 }
01045 
01046 
01047 static void *
01048 tf_send (void *arg)
01049 {
01050   struct sockaddr_un sun;
01051 
01052   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
01053   if (tempfd == -1)
01054     {
01055       printf ("%s: first socket call failed\n", __FUNCTION__);
01056       exit (1);
01057     }
01058 
01059   int tries = 0;
01060   do
01061     {
01062       if (++tries > 10)
01063        {
01064          printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
01065        }
01066 
01067       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
01068       if (mktemp (sun.sun_path) == NULL)
01069        {
01070          printf ("%s: cannot generate temp file name\n", __FUNCTION__);
01071          exit (1);
01072        }
01073 
01074       sun.sun_family = AF_UNIX;
01075     }
01076   while (bind (tempfd, (struct sockaddr *) &sun,
01077               offsetof (struct sockaddr_un, sun_path)
01078               + strlen (sun.sun_path) + 1) != 0);
01079 
01080   listen (tempfd, 5);
01081 
01082   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
01083   if (tempfd2 == -1)
01084     {
01085       printf ("%s: second socket call failed\n", __FUNCTION__);
01086       exit (1);
01087     }
01088 
01089   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
01090     {
01091       printf ("%s: connect failed\n", __FUNCTION__);
01092       exit(1);
01093     }
01094 
01095   unlink (sun.sun_path);
01096 
01097   int r = pthread_barrier_wait (&b2);
01098   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01099     {
01100       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01101       exit (1);
01102     }
01103 
01104   if (arg != NULL)
01105     {
01106       r = pthread_barrier_wait (&b2);
01107       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01108        {
01109          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01110          exit (1);
01111        }
01112     }
01113 
01114   pthread_cleanup_push (cl, NULL);
01115 
01116   /* Very large block, so that the send call blocks.  */
01117   char mem[700000];
01118 
01119   send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
01120 
01121   pthread_cleanup_pop (0);
01122 
01123   printf ("%s: send returned\n", __FUNCTION__);
01124 
01125   exit (1);
01126 }
01127 
01128 
01129 static void *
01130 tf_recv (void *arg)
01131 {
01132   struct sockaddr_un sun;
01133 
01134   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
01135   if (tempfd == -1)
01136     {
01137       printf ("%s: first socket call failed\n", __FUNCTION__);
01138       exit (1);
01139     }
01140 
01141   int tries = 0;
01142   do
01143     {
01144       if (++tries > 10)
01145        {
01146          printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
01147        }
01148 
01149       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
01150       if (mktemp (sun.sun_path) == NULL)
01151        {
01152          printf ("%s: cannot generate temp file name\n", __FUNCTION__);
01153          exit (1);
01154        }
01155 
01156       sun.sun_family = AF_UNIX;
01157     }
01158   while (bind (tempfd, (struct sockaddr *) &sun,
01159               offsetof (struct sockaddr_un, sun_path)
01160               + strlen (sun.sun_path) + 1) != 0);
01161 
01162   listen (tempfd, 5);
01163 
01164   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
01165   if (tempfd2 == -1)
01166     {
01167       printf ("%s: second socket call failed\n", __FUNCTION__);
01168       exit (1);
01169     }
01170 
01171   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
01172     {
01173       printf ("%s: connect failed\n", __FUNCTION__);
01174       exit(1);
01175     }
01176 
01177   unlink (sun.sun_path);
01178 
01179   int r = pthread_barrier_wait (&b2);
01180   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01181     {
01182       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01183       exit (1);
01184     }
01185 
01186   if (arg != NULL)
01187     {
01188       r = pthread_barrier_wait (&b2);
01189       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01190        {
01191          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01192          exit (1);
01193        }
01194     }
01195 
01196   pthread_cleanup_push (cl, NULL);
01197 
01198   char mem[70];
01199 
01200   recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
01201 
01202   pthread_cleanup_pop (0);
01203 
01204   printf ("%s: recv returned\n", __FUNCTION__);
01205 
01206   exit (1);
01207 }
01208 
01209 
01210 static void *
01211 tf_recvfrom (void *arg)
01212 {
01213   struct sockaddr_un sun;
01214 
01215   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
01216   if (tempfd == -1)
01217     {
01218       printf ("%s: first socket call failed\n", __FUNCTION__);
01219       exit (1);
01220     }
01221 
01222   int tries = 0;
01223   do
01224     {
01225       if (++tries > 10)
01226        {
01227          printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
01228        }
01229 
01230       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
01231       if (mktemp (sun.sun_path) == NULL)
01232        {
01233          printf ("%s: cannot generate temp file name\n", __FUNCTION__);
01234          exit (1);
01235        }
01236 
01237       sun.sun_family = AF_UNIX;
01238     }
01239   while (bind (tempfd, (struct sockaddr *) &sun,
01240               offsetof (struct sockaddr_un, sun_path)
01241               + strlen (sun.sun_path) + 1) != 0);
01242 
01243   tempfname = strdup (sun.sun_path);
01244 
01245   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
01246   if (tempfd2 == -1)
01247     {
01248       printf ("%s: second socket call failed\n", __FUNCTION__);
01249       exit (1);
01250     }
01251 
01252   int r = pthread_barrier_wait (&b2);
01253   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01254     {
01255       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01256       exit (1);
01257     }
01258 
01259   if (arg != NULL)
01260     {
01261       r = pthread_barrier_wait (&b2);
01262       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01263        {
01264          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01265          exit (1);
01266        }
01267     }
01268 
01269   pthread_cleanup_push (cl, NULL);
01270 
01271   char mem[70];
01272   socklen_t len = sizeof (sun);
01273 
01274   recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
01275            (struct sockaddr *) &sun, &len);
01276 
01277   pthread_cleanup_pop (0);
01278 
01279   printf ("%s: recvfrom returned\n", __FUNCTION__);
01280 
01281   exit (1);
01282 }
01283 
01284 
01285 static void *
01286 tf_recvmsg (void *arg)
01287 {
01288   struct sockaddr_un sun;
01289 
01290   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
01291   if (tempfd == -1)
01292     {
01293       printf ("%s: first socket call failed\n", __FUNCTION__);
01294       exit (1);
01295     }
01296 
01297   int tries = 0;
01298   do
01299     {
01300       if (++tries > 10)
01301        {
01302          printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
01303        }
01304 
01305       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
01306       if (mktemp (sun.sun_path) == NULL)
01307        {
01308          printf ("%s: cannot generate temp file name\n", __FUNCTION__);
01309          exit (1);
01310        }
01311 
01312       sun.sun_family = AF_UNIX;
01313     }
01314   while (bind (tempfd, (struct sockaddr *) &sun,
01315               offsetof (struct sockaddr_un, sun_path)
01316               + strlen (sun.sun_path) + 1) != 0);
01317 
01318   tempfname = strdup (sun.sun_path);
01319 
01320   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
01321   if (tempfd2 == -1)
01322     {
01323       printf ("%s: second socket call failed\n", __FUNCTION__);
01324       exit (1);
01325     }
01326 
01327   int r = pthread_barrier_wait (&b2);
01328   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01329     {
01330       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01331       exit (1);
01332     }
01333 
01334   if (arg != NULL)
01335     {
01336       r = pthread_barrier_wait (&b2);
01337       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01338        {
01339          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01340          exit (1);
01341        }
01342     }
01343 
01344   pthread_cleanup_push (cl, NULL);
01345 
01346   char mem[70];
01347   struct iovec iov[1];
01348   iov[0].iov_base = mem;
01349   iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
01350 
01351   struct msghdr m;
01352   m.msg_name = &sun;
01353   m.msg_namelen = sizeof (sun);
01354   m.msg_iov = iov;
01355   m.msg_iovlen = 1;
01356   m.msg_control = NULL;
01357   m.msg_controllen = 0;
01358 
01359   recvmsg (tempfd2, &m, 0);
01360 
01361   pthread_cleanup_pop (0);
01362 
01363   printf ("%s: recvmsg returned\n", __FUNCTION__);
01364 
01365   exit (1);
01366 }
01367 
01368 
01369 static void *
01370 tf_open (void *arg)
01371 {
01372   if (arg == NULL)
01373     // XXX If somebody can provide a portable test case in which open()
01374     // blocks we can enable this test to run in both rounds.
01375     abort ();
01376 
01377   int r = pthread_barrier_wait (&b2);
01378   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01379     {
01380       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01381       exit (1);
01382     }
01383 
01384   r = pthread_barrier_wait (&b2);
01385   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01386     {
01387       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01388       exit (1);
01389     }
01390 
01391   pthread_cleanup_push (cl, NULL);
01392 
01393   open ("Makefile", O_RDONLY);
01394 
01395   pthread_cleanup_pop (0);
01396 
01397   printf ("%s: open returned\n", __FUNCTION__);
01398 
01399   exit (1);
01400 }
01401 
01402 
01403 static void *
01404 tf_close (void *arg)
01405 {
01406   if (arg == NULL)
01407     // XXX If somebody can provide a portable test case in which close()
01408     // blocks we can enable this test to run in both rounds.
01409     abort ();
01410 
01411   char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
01412   tempfd = mkstemp (fname);
01413   if (tempfd == -1)
01414     {
01415       printf ("%s: mkstemp failed\n", __FUNCTION__);
01416       exit (1);
01417     }
01418   unlink (fname);
01419 
01420   int r = pthread_barrier_wait (&b2);
01421   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01422     {
01423       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01424       exit (1);
01425     }
01426 
01427   r = pthread_barrier_wait (&b2);
01428   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01429     {
01430       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01431       exit (1);
01432     }
01433 
01434   pthread_cleanup_push (cl, NULL);
01435 
01436   close (tempfd);
01437 
01438   pthread_cleanup_pop (0);
01439 
01440   printf ("%s: close returned\n", __FUNCTION__);
01441 
01442   exit (1);
01443 }
01444 
01445 
01446 static void *
01447 tf_pread (void *arg)
01448 {
01449   if (arg == NULL)
01450     // XXX If somebody can provide a portable test case in which pread()
01451     // blocks we can enable this test to run in both rounds.
01452     abort ();
01453 
01454   tempfd = open ("Makefile", O_RDONLY);
01455   if (tempfd == -1)
01456     {
01457       printf ("%s: cannot open Makefile\n", __FUNCTION__);
01458       exit (1);
01459     }
01460 
01461   int r = pthread_barrier_wait (&b2);
01462   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01463     {
01464       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01465       exit (1);
01466     }
01467 
01468   r = pthread_barrier_wait (&b2);
01469   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01470     {
01471       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01472       exit (1);
01473     }
01474 
01475   pthread_cleanup_push (cl, NULL);
01476 
01477   char mem[10];
01478   pread (tempfd, mem, sizeof (mem), 0);
01479 
01480   pthread_cleanup_pop (0);
01481 
01482   printf ("%s: pread returned\n", __FUNCTION__);
01483 
01484   exit (1);
01485 }
01486 
01487 
01488 static void *
01489 tf_pwrite (void *arg)
01490 {
01491   if (arg == NULL)
01492     // XXX If somebody can provide a portable test case in which pwrite()
01493     // blocks we can enable this test to run in both rounds.
01494     abort ();
01495 
01496   char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
01497   tempfd = mkstemp (fname);
01498   if (tempfd == -1)
01499     {
01500       printf ("%s: mkstemp failed\n", __FUNCTION__);
01501       exit (1);
01502     }
01503   unlink (fname);
01504 
01505   int r = pthread_barrier_wait (&b2);
01506   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01507     {
01508       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01509       exit (1);
01510     }
01511 
01512   r = pthread_barrier_wait (&b2);
01513   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01514     {
01515       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01516       exit (1);
01517     }
01518 
01519   pthread_cleanup_push (cl, NULL);
01520 
01521   char mem[10];
01522   pwrite (tempfd, mem, sizeof (mem), 0);
01523 
01524   pthread_cleanup_pop (0);
01525 
01526   printf ("%s: pwrite returned\n", __FUNCTION__);
01527 
01528   exit (1);
01529 }
01530 
01531 
01532 static void *
01533 tf_fsync (void *arg)
01534 {
01535   if (arg == NULL)
01536     // XXX If somebody can provide a portable test case in which fsync()
01537     // blocks we can enable this test to run in both rounds.
01538     abort ();
01539 
01540   tempfd = open ("Makefile", O_RDONLY);
01541   if (tempfd == -1)
01542     {
01543       printf ("%s: cannot open Makefile\n", __FUNCTION__);
01544       exit (1);
01545     }
01546 
01547   int r = pthread_barrier_wait (&b2);
01548   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01549     {
01550       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01551       exit (1);
01552     }
01553 
01554   r = pthread_barrier_wait (&b2);
01555   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01556     {
01557       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01558       exit (1);
01559     }
01560 
01561   pthread_cleanup_push (cl, NULL);
01562 
01563   fsync (tempfd);
01564 
01565   pthread_cleanup_pop (0);
01566 
01567   printf ("%s: fsync returned\n", __FUNCTION__);
01568 
01569   exit (1);
01570 }
01571 
01572 
01573 static void *
01574 tf_fdatasync (void *arg)
01575 {
01576   if (arg == NULL)
01577     // XXX If somebody can provide a portable test case in which fdatasync()
01578     // blocks we can enable this test to run in both rounds.
01579     abort ();
01580 
01581   tempfd = open ("Makefile", O_RDONLY);
01582   if (tempfd == -1)
01583     {
01584       printf ("%s: cannot open Makefile\n", __FUNCTION__);
01585       exit (1);
01586     }
01587 
01588   int r = pthread_barrier_wait (&b2);
01589   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01590     {
01591       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01592       exit (1);
01593     }
01594 
01595   r = pthread_barrier_wait (&b2);
01596   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01597     {
01598       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01599       exit (1);
01600     }
01601 
01602   pthread_cleanup_push (cl, NULL);
01603 
01604   fdatasync (tempfd);
01605 
01606   pthread_cleanup_pop (0);
01607 
01608   printf ("%s: fdatasync returned\n", __FUNCTION__);
01609 
01610   exit (1);
01611 }
01612 
01613 
01614 static void *
01615 tf_msync (void *arg)
01616 {
01617   if (arg == NULL)
01618     // XXX If somebody can provide a portable test case in which msync()
01619     // blocks we can enable this test to run in both rounds.
01620     abort ();
01621 
01622   tempfd = open ("Makefile", O_RDONLY);
01623   if (tempfd == -1)
01624     {
01625       printf ("%s: cannot open Makefile\n", __FUNCTION__);
01626       exit (1);
01627     }
01628   void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
01629   if (p == MAP_FAILED)
01630     {
01631       printf ("%s: mmap failed\n", __FUNCTION__);
01632       exit (1);
01633     }
01634 
01635   int r = pthread_barrier_wait (&b2);
01636   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01637     {
01638       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01639       exit (1);
01640     }
01641 
01642   r = pthread_barrier_wait (&b2);
01643   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01644     {
01645       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01646       exit (1);
01647     }
01648 
01649   pthread_cleanup_push (cl, NULL);
01650 
01651   msync (p, 10, 0);
01652 
01653   pthread_cleanup_pop (0);
01654 
01655   printf ("%s: msync returned\n", __FUNCTION__);
01656 
01657   exit (1);
01658 }
01659 
01660 
01661 static void *
01662 tf_sendto (void *arg)
01663 {
01664   if (arg == NULL)
01665     // XXX If somebody can provide a portable test case in which sendto()
01666     // blocks we can enable this test to run in both rounds.
01667     abort ();
01668 
01669   struct sockaddr_un sun;
01670 
01671   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
01672   if (tempfd == -1)
01673     {
01674       printf ("%s: first socket call failed\n", __FUNCTION__);
01675       exit (1);
01676     }
01677 
01678   int tries = 0;
01679   do
01680     {
01681       if (++tries > 10)
01682        {
01683          printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
01684        }
01685 
01686       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
01687       if (mktemp (sun.sun_path) == NULL)
01688        {
01689          printf ("%s: cannot generate temp file name\n", __FUNCTION__);
01690          exit (1);
01691        }
01692 
01693       sun.sun_family = AF_UNIX;
01694     }
01695   while (bind (tempfd, (struct sockaddr *) &sun,
01696               offsetof (struct sockaddr_un, sun_path)
01697               + strlen (sun.sun_path) + 1) != 0);
01698   tempfname = strdup (sun.sun_path);
01699 
01700   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
01701   if (tempfd2 == -1)
01702     {
01703       printf ("%s: second socket call failed\n", __FUNCTION__);
01704       exit (1);
01705     }
01706 
01707   int r = pthread_barrier_wait (&b2);
01708   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01709     {
01710       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01711       exit (1);
01712     }
01713 
01714   r = pthread_barrier_wait (&b2);
01715   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01716     {
01717       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01718       exit (1);
01719     }
01720 
01721   pthread_cleanup_push (cl, NULL);
01722 
01723   char mem[1];
01724 
01725   sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
01726          (struct sockaddr *) &sun,
01727          offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
01728 
01729   pthread_cleanup_pop (0);
01730 
01731   printf ("%s: sendto returned\n", __FUNCTION__);
01732 
01733   exit (1);
01734 }
01735 
01736 
01737 static void *
01738 tf_sendmsg (void *arg)
01739 {
01740   if (arg == NULL)
01741     // XXX If somebody can provide a portable test case in which sendmsg()
01742     // blocks we can enable this test to run in both rounds.
01743     abort ();
01744 
01745   struct sockaddr_un sun;
01746 
01747   tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
01748   if (tempfd == -1)
01749     {
01750       printf ("%s: first socket call failed\n", __FUNCTION__);
01751       exit (1);
01752     }
01753 
01754   int tries = 0;
01755   do
01756     {
01757       if (++tries > 10)
01758        {
01759          printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
01760        }
01761 
01762       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
01763       if (mktemp (sun.sun_path) == NULL)
01764        {
01765          printf ("%s: cannot generate temp file name\n", __FUNCTION__);
01766          exit (1);
01767        }
01768 
01769       sun.sun_family = AF_UNIX;
01770     }
01771   while (bind (tempfd, (struct sockaddr *) &sun,
01772               offsetof (struct sockaddr_un, sun_path)
01773               + strlen (sun.sun_path) + 1) != 0);
01774   tempfname = strdup (sun.sun_path);
01775 
01776   tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
01777   if (tempfd2 == -1)
01778     {
01779       printf ("%s: second socket call failed\n", __FUNCTION__);
01780       exit (1);
01781     }
01782 
01783   int r = pthread_barrier_wait (&b2);
01784   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01785     {
01786       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01787       exit (1);
01788     }
01789 
01790   r = pthread_barrier_wait (&b2);
01791   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01792     {
01793       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01794       exit (1);
01795     }
01796 
01797   pthread_cleanup_push (cl, NULL);
01798 
01799   char mem[1];
01800   struct iovec iov[1];
01801   iov[0].iov_base = mem;
01802   iov[0].iov_len = 1;
01803 
01804   struct msghdr m;
01805   m.msg_name = &sun;
01806   m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
01807                  + strlen (sun.sun_path) + 1);
01808   m.msg_iov = iov;
01809   m.msg_iovlen = 1;
01810   m.msg_control = NULL;
01811   m.msg_controllen = 0;
01812 
01813   sendmsg (tempfd2, &m, 0);
01814 
01815   pthread_cleanup_pop (0);
01816 
01817   printf ("%s: sendmsg returned\n", __FUNCTION__);
01818 
01819   exit (1);
01820 }
01821 
01822 
01823 static void *
01824 tf_creat (void *arg)
01825 {
01826   if (arg == NULL)
01827     // XXX If somebody can provide a portable test case in which sendmsg()
01828     // blocks we can enable this test to run in both rounds.
01829     abort ();
01830 
01831   int r = pthread_barrier_wait (&b2);
01832   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01833     {
01834       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01835       exit (1);
01836     }
01837 
01838   r = pthread_barrier_wait (&b2);
01839   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01840     {
01841       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01842       exit (1);
01843     }
01844 
01845   pthread_cleanup_push (cl, NULL);
01846 
01847   creat ("tmp/tst-cancel-4-should-not-exist", 0666);
01848 
01849   pthread_cleanup_pop (0);
01850 
01851   printf ("%s: creat returned\n", __FUNCTION__);
01852 
01853   exit (1);
01854 }
01855 
01856 
01857 static void *
01858 tf_connect (void *arg)
01859 {
01860   if (arg == NULL)
01861     // XXX If somebody can provide a portable test case in which connect()
01862     // blocks we can enable this test to run in both rounds.
01863     abort ();
01864 
01865   struct sockaddr_un sun;
01866 
01867   tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
01868   if (tempfd == -1)
01869     {
01870       printf ("%s: first socket call failed\n", __FUNCTION__);
01871       exit (1);
01872     }
01873 
01874   int tries = 0;
01875   do
01876     {
01877       if (++tries > 10)
01878        {
01879          printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
01880        }
01881 
01882       strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
01883       if (mktemp (sun.sun_path) == NULL)
01884        {
01885          printf ("%s: cannot generate temp file name\n", __FUNCTION__);
01886          exit (1);
01887        }
01888 
01889       sun.sun_family = AF_UNIX;
01890     }
01891   while (bind (tempfd, (struct sockaddr *) &sun,
01892               offsetof (struct sockaddr_un, sun_path)
01893               + strlen (sun.sun_path) + 1) != 0);
01894   tempfname = strdup (sun.sun_path);
01895 
01896   listen (tempfd, 5);
01897 
01898   tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
01899   if (tempfd2 == -1)
01900     {
01901       printf ("%s: second socket call failed\n", __FUNCTION__);
01902       exit (1);
01903     }
01904 
01905   int r = pthread_barrier_wait (&b2);
01906   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01907     {
01908       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01909       exit (1);
01910     }
01911 
01912   if (arg != NULL)
01913     {
01914       r = pthread_barrier_wait (&b2);
01915       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01916        {
01917          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01918          exit (1);
01919        }
01920     }
01921 
01922   pthread_cleanup_push (cl, NULL);
01923 
01924   connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
01925 
01926   pthread_cleanup_pop (0);
01927 
01928   printf ("%s: connect returned\n", __FUNCTION__);
01929 
01930   exit (1);
01931 }
01932 
01933 
01934 static void *
01935 tf_tcdrain (void *arg)
01936 {
01937   if (arg == NULL)
01938     // XXX If somebody can provide a portable test case in which tcdrain()
01939     // blocks we can enable this test to run in both rounds.
01940     abort ();
01941 
01942   int r = pthread_barrier_wait (&b2);
01943   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01944     {
01945       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01946       exit (1);
01947     }
01948 
01949   if (arg != NULL)
01950     {
01951       r = pthread_barrier_wait (&b2);
01952       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01953        {
01954          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01955          exit (1);
01956        }
01957     }
01958 
01959   pthread_cleanup_push (cl, NULL);
01960 
01961   /* Regardless of stderr being a terminal, the tcdrain call should be
01962      canceled.  */
01963   tcdrain (STDERR_FILENO);
01964 
01965   pthread_cleanup_pop (0);
01966 
01967   printf ("%s: tcdrain returned\n", __FUNCTION__);
01968 
01969   exit (1);
01970 }
01971 
01972 
01973 static void *
01974 tf_msgrcv (void *arg)
01975 {
01976   tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
01977   if (tempmsg == -1)
01978     {
01979       printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
01980       exit (1);
01981     }
01982 
01983   int r = pthread_barrier_wait (&b2);
01984   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01985     {
01986       printf ("%s: barrier_wait failed\n", __FUNCTION__);
01987       exit (1);
01988     }
01989 
01990   if (arg != NULL)
01991     {
01992       r = pthread_barrier_wait (&b2);
01993       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
01994        {
01995          printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
01996          exit (1);
01997        }
01998     }
01999 
02000   ssize_t s;
02001 
02002   pthread_cleanup_push (cl, NULL);
02003 
02004   struct
02005   {
02006     long int type;
02007     char mem[10];
02008   } m;
02009   int randnr;
02010   /* We need a positive random number.  */
02011   do
02012     randnr = random () % 64000;
02013   while (randnr <= 0);
02014   do
02015     {
02016       errno = 0;
02017       s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
02018     }
02019   while (errno == EIDRM || errno == EINTR);
02020 
02021   pthread_cleanup_pop (0);
02022 
02023   printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);
02024 
02025   msgctl (tempmsg, IPC_RMID, NULL);
02026 
02027   exit (1);
02028 }
02029 
02030 
02031 static void *
02032 tf_msgsnd (void *arg)
02033 {
02034   if (arg == NULL)
02035     // XXX If somebody can provide a portable test case in which msgsnd()
02036     // blocks we can enable this test to run in both rounds.
02037     abort ();
02038 
02039   tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
02040   if (tempmsg == -1)
02041     {
02042       printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
02043       exit (1);
02044     }
02045 
02046   int r = pthread_barrier_wait (&b2);
02047   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
02048     {
02049       printf ("%s: barrier_wait failed\n", __FUNCTION__);
02050       exit (1);
02051     }
02052 
02053   r = pthread_barrier_wait (&b2);
02054   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
02055     {
02056       printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
02057       exit (1);
02058     }
02059 
02060   pthread_cleanup_push (cl, NULL);
02061 
02062   struct
02063   {
02064     long int type;
02065     char mem[1];
02066   } m;
02067   /* We need a positive random number.  */
02068   do
02069     m.type = random () % 64000;
02070   while (m.type <= 0);
02071   msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
02072 
02073   pthread_cleanup_pop (0);
02074 
02075   printf ("%s: msgsnd returned\n", __FUNCTION__);
02076 
02077   msgctl (tempmsg, IPC_RMID, NULL);
02078 
02079   exit (1);
02080 }
02081 
02082 
02083 static struct
02084 {
02085   const char *name;
02086   void *(*tf) (void *);
02087   int nb;
02088   int only_early;
02089 } tests[] =
02090 {
02091 #define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early }
02092   ADD_TEST (read, 2, 0),
02093   ADD_TEST (readv, 2, 0),
02094   ADD_TEST (select, 2, 0),
02095   ADD_TEST (pselect, 2, 0),
02096   ADD_TEST (poll, 2, 0),
02097   ADD_TEST (ppoll, 2, 0),
02098   ADD_TEST (write, 2, 0),
02099   ADD_TEST (writev, 2, 0),
02100   ADD_TEST (sleep, 2, 0),
02101   ADD_TEST (usleep, 2, 0),
02102   ADD_TEST (nanosleep, 2, 0),
02103   ADD_TEST (wait, 2, 0),
02104   ADD_TEST (waitid, 2, 0),
02105   ADD_TEST (waitpid, 2, 0),
02106   ADD_TEST (sigpause, 2, 0),
02107   ADD_TEST (sigsuspend, 2, 0),
02108   ADD_TEST (sigwait, 2, 0),
02109   ADD_TEST (sigwaitinfo, 2, 0),
02110   ADD_TEST (sigtimedwait, 2, 0),
02111   ADD_TEST (pause, 2, 0),
02112   ADD_TEST (accept, 2, 0),
02113   ADD_TEST (send, 2, 0),
02114   ADD_TEST (recv, 2, 0),
02115   ADD_TEST (recvfrom, 2, 0),
02116   ADD_TEST (recvmsg, 2, 0),
02117   ADD_TEST (open, 2, 1),
02118   ADD_TEST (close, 2, 1),
02119   ADD_TEST (pread, 2, 1),
02120   ADD_TEST (pwrite, 2, 1),
02121   ADD_TEST (fsync, 2, 1),
02122   ADD_TEST (fdatasync, 2, 1),
02123   ADD_TEST (msync, 2, 1),
02124   ADD_TEST (sendto, 2, 1),
02125   ADD_TEST (sendmsg, 2, 1),
02126   ADD_TEST (creat, 2, 1),
02127   ADD_TEST (connect, 2, 1),
02128   ADD_TEST (tcdrain, 2, 1),
02129   ADD_TEST (msgrcv, 2, 0),
02130   ADD_TEST (msgsnd, 2, 1),
02131 };
02132 #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
02133 
02134 
02135 static int
02136 do_test (void)
02137 {
02138   int val;
02139   socklen_t len;
02140 
02141   if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
02142     {
02143       perror ("socketpair");
02144       exit (1);
02145     }
02146 
02147   val = 1;
02148   len = sizeof(val);
02149   setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
02150   if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
02151     {
02152       perror ("getsockopt");
02153       exit (1);
02154     }
02155   if (val >= WRITE_BUFFER_SIZE)
02156     {
02157       puts ("minimum write buffer size too large");
02158       exit (1);
02159     }
02160   setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
02161 
02162   int result = 0;
02163   size_t cnt;
02164   for (cnt = 0; cnt < ntest_tf; ++cnt)
02165     {
02166       if (tests[cnt].only_early)
02167        continue;
02168 
02169       if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
02170        {
02171          puts ("b2 init failed");
02172          exit (1);
02173        }
02174 
02175       /* Reset the counter for the cleanup handler.  */
02176       cl_called = 0;
02177 
02178       pthread_t th;
02179       if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
02180        {
02181          printf ("create for '%s' test failed\n", tests[cnt].name);
02182          result = 1;
02183          continue;
02184        }
02185 
02186       int r = pthread_barrier_wait (&b2);
02187       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
02188        {
02189          printf ("%s: barrier_wait failed\n", __FUNCTION__);
02190          result = 1;
02191          continue;
02192        }
02193 
02194       struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
02195       while (nanosleep (&ts, &ts) != 0)
02196        continue;
02197 
02198       if (pthread_cancel (th) != 0)
02199        {
02200          printf ("cancel for '%s' failed\n", tests[cnt].name);
02201          result = 1;
02202          continue;
02203        }
02204 
02205       void *status;
02206       if (pthread_join (th, &status) != 0)
02207        {
02208          printf ("join for '%s' failed\n", tests[cnt].name);
02209          result = 1;
02210          continue;
02211        }
02212       if (status != PTHREAD_CANCELED)
02213        {
02214          printf ("thread for '%s' not canceled\n", tests[cnt].name);
02215          result = 1;
02216          continue;
02217        }
02218 
02219       if (pthread_barrier_destroy (&b2) != 0)
02220        {
02221          puts ("barrier_destroy failed");
02222          result = 1;
02223          continue;
02224        }
02225 
02226       if (cl_called == 0)
02227        {
02228          printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
02229          result = 1;
02230          continue;
02231        }
02232       if (cl_called > 1)
02233        {
02234          printf ("cleanup handler called more than once for '%s'\n",
02235                 tests[cnt].name);
02236          result = 1;
02237          continue;
02238        }
02239 
02240       printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);
02241 
02242       if (tempfd != -1)
02243        {
02244          close (tempfd);
02245          tempfd = -1;
02246        }
02247       if (tempfd2 != -1)
02248        {
02249          close (tempfd2);
02250          tempfd2 = -1;
02251        }
02252       if (tempfname != NULL)
02253        {
02254          unlink (tempfname);
02255          free (tempfname);
02256          tempfname = NULL;
02257        }
02258       if (tempmsg != -1)
02259        {
02260          msgctl (tempmsg, IPC_RMID, NULL);
02261          tempmsg = -1;
02262        }
02263     }
02264 
02265   for (cnt = 0; cnt < ntest_tf; ++cnt)
02266     {
02267       if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
02268        {
02269          puts ("b2 init failed");
02270          exit (1);
02271        }
02272 
02273       /* Reset the counter for the cleanup handler.  */
02274       cl_called = 0;
02275 
02276       pthread_t th;
02277       if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
02278        {
02279          printf ("create for '%s' test failed\n", tests[cnt].name);
02280          result = 1;
02281          continue;
02282        }
02283 
02284       int r = pthread_barrier_wait (&b2);
02285       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
02286        {
02287          printf ("%s: barrier_wait failed\n", __FUNCTION__);
02288          result = 1;
02289          continue;
02290        }
02291 
02292       if (pthread_cancel (th) != 0)
02293        {
02294          printf ("cancel for '%s' failed\n", tests[cnt].name);
02295          result = 1;
02296          continue;
02297        }
02298 
02299       r = pthread_barrier_wait (&b2);
02300       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
02301        {
02302          printf ("%s: barrier_wait failed\n", __FUNCTION__);
02303          result = 1;
02304          continue;
02305        }
02306 
02307       void *status;
02308       if (pthread_join (th, &status) != 0)
02309        {
02310          printf ("join for '%s' failed\n", tests[cnt].name);
02311          result = 1;
02312          continue;
02313        }
02314       if (status != PTHREAD_CANCELED)
02315        {
02316          printf ("thread for '%s' not canceled\n", tests[cnt].name);
02317          result = 1;
02318          continue;
02319        }
02320 
02321       if (pthread_barrier_destroy (&b2) != 0)
02322        {
02323          puts ("barrier_destroy failed");
02324          result = 1;
02325          continue;
02326        }
02327 
02328       if (cl_called == 0)
02329        {
02330          printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
02331          result = 1;
02332          continue;
02333        }
02334       if (cl_called > 1)
02335        {
02336          printf ("cleanup handler called more than once for '%s'\n",
02337                 tests[cnt].name);
02338          result = 1;
02339          continue;
02340        }
02341 
02342       printf ("early cancel test of '%s' successful\n", tests[cnt].name);
02343 
02344       if (tempfd != -1)
02345        {
02346          close (tempfd);
02347          tempfd = -1;
02348        }
02349       if (tempfd2 != -1)
02350        {
02351          close (tempfd2);
02352          tempfd2 = -1;
02353        }
02354       if (tempfname != NULL)
02355        {
02356          unlink (tempfname);
02357          free (tempfname);
02358          tempfname = NULL;
02359        }
02360       if (tempmsg != -1)
02361        {
02362          msgctl (tempmsg, IPC_RMID, NULL);
02363          tempmsg = -1;
02364        }
02365     }
02366 
02367   return result;
02368 }
02369 
02370 #define TIMEOUT 60
02371 #define TEST_FUNCTION do_test ()
02372 #include "../test-skeleton.c"