Back to index

glibc  2.9
tst-cancel19.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
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 #include <errno.h>
00021 #include <error.h>
00022 #include <fcntl.h>
00023 #include <pthread.h>
00024 #include <signal.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <sys/select.h>
00029 #include <sys/time.h>
00030 #include <unistd.h>
00031 
00032 static void *
00033 tf (void *arg)
00034 {
00035   return NULL;
00036 }
00037 
00038 static void
00039 handler (int sig)
00040 {
00041 }
00042 
00043 static void __attribute__ ((noinline))
00044 clobber_lots_of_regs (void)
00045 {
00046 #define X1(n) long r##n = 10##n; __asm __volatile ("" : "+r" (r##n));
00047 #define X2(n) X1(n##0) X1(n##1) X1(n##2) X1(n##3) X1(n##4)
00048 #define X3(n) X2(n##0) X2(n##1) X2(n##2) X2(n##3) X2(n##4)
00049   X3(0) X3(1) X3(2) X3(3) X3(4)
00050 #undef X1
00051 #define X1(n) __asm __volatile ("" : : "r" (r##n));
00052   X3(0) X3(1) X3(2) X3(3) X3(4)
00053 #undef X1
00054 #undef X2
00055 #undef X3
00056 }
00057 
00058 static int
00059 do_test (void)
00060 {
00061   pthread_t th;
00062   int old, rc;
00063   int ret = 0;
00064   int fd[2];
00065 
00066   rc = pipe (fd);
00067   if (rc < 0)
00068     error (EXIT_FAILURE, errno, "couldn't create pipe");
00069 
00070   rc = pthread_create (&th, NULL, tf, NULL);
00071   if (rc)
00072     error (EXIT_FAILURE, rc, "couldn't create thread");
00073 
00074   rc = pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &old);
00075   if (rc)
00076     {
00077       error (0, rc, "1st pthread_setcanceltype failed");
00078       ret = 1;
00079     }
00080   if (old != PTHREAD_CANCEL_DEFERRED && old != PTHREAD_CANCEL_ASYNCHRONOUS)
00081     {
00082       error (0, 0, "1st pthread_setcanceltype returned invalid value %d",
00083             old);
00084       ret = 1;
00085     }
00086 
00087   clobber_lots_of_regs ();
00088   close (fd[0]);
00089 
00090   rc = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &old);
00091   if (rc)
00092     {
00093       error (0, rc, "pthread_setcanceltype after close failed");
00094       ret = 1;
00095     }
00096   if (old != PTHREAD_CANCEL_DEFERRED)
00097     {
00098       error (0, 0, "pthread_setcanceltype after close returned invalid value %d",
00099             old);
00100       ret = 1;
00101     }
00102 
00103   clobber_lots_of_regs ();
00104   close (fd[1]);
00105 
00106   rc = pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &old);
00107   if (rc)
00108     {
00109       error (0, rc, "pthread_setcanceltype after 2nd close failed");
00110       ret = 1;
00111     }
00112   if (old != PTHREAD_CANCEL_ASYNCHRONOUS)
00113     {
00114       error (0, 0, "pthread_setcanceltype after 2nd close returned invalid value %d",
00115             old);
00116       ret = 1;
00117     }
00118 
00119   struct sigaction sa = { .sa_handler = handler, .sa_flags = 0 };
00120   sigemptyset (&sa.sa_mask);
00121   sigaction (SIGALRM, &sa, NULL);
00122 
00123   struct itimerval it;
00124   it.it_value.tv_sec = 1;
00125   it.it_value.tv_usec = 0;
00126   it.it_interval = it.it_value;
00127   setitimer (ITIMER_REAL, &it, NULL);
00128 
00129   clobber_lots_of_regs ();
00130   pause ();
00131 
00132   memset (&it, 0, sizeof (it));
00133   setitimer (ITIMER_REAL, &it, NULL);
00134 
00135   rc = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &old);
00136   if (rc)
00137     {
00138       error (0, rc, "pthread_setcanceltype after pause failed");
00139       ret = 1;
00140     }
00141   if (old != PTHREAD_CANCEL_DEFERRED)
00142     {
00143       error (0, 0, "pthread_setcanceltype after pause returned invalid value %d",
00144             old);
00145       ret = 1;
00146     }
00147 
00148   it.it_value.tv_sec = 1;
00149   it.it_value.tv_usec = 0;
00150   it.it_interval = it.it_value;
00151   setitimer (ITIMER_REAL, &it, NULL);
00152 
00153   clobber_lots_of_regs ();
00154   pause ();
00155 
00156   memset (&it, 0, sizeof (it));
00157   setitimer (ITIMER_REAL, &it, NULL);
00158 
00159   rc = pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &old);
00160   if (rc)
00161     {
00162       error (0, rc, "pthread_setcanceltype after 2nd pause failed");
00163       ret = 1;
00164     }
00165   if (old != PTHREAD_CANCEL_ASYNCHRONOUS)
00166     {
00167       error (0, 0, "pthread_setcanceltype after 2nd pause returned invalid value %d",
00168             old);
00169       ret = 1;
00170     }
00171 
00172   char fname[] = "/tmp/tst-cancel19-dir-XXXXXX\0foo/bar";
00173   char *enddir = strchr (fname, '\0');
00174   if (mkdtemp (fname) == NULL)
00175     {
00176       error (0, errno, "mkdtemp failed");
00177       ret = 1;
00178     }
00179   *enddir = '/';
00180 
00181   clobber_lots_of_regs ();
00182   creat (fname, 0400);
00183 
00184   rc = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &old);
00185   if (rc)
00186     {
00187       error (0, rc, "pthread_setcanceltype after creat failed");
00188       ret = 1;
00189     }
00190   if (old != PTHREAD_CANCEL_DEFERRED)
00191     {
00192       error (0, 0, "pthread_setcanceltype after creat returned invalid value %d",
00193             old);
00194       ret = 1;
00195     }
00196 
00197   clobber_lots_of_regs ();
00198   creat (fname, 0400);
00199 
00200   rc = pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &old);
00201   if (rc)
00202     {
00203       error (0, rc, "pthread_setcanceltype after 2nd creat failed");
00204       ret = 1;
00205     }
00206   if (old != PTHREAD_CANCEL_ASYNCHRONOUS)
00207     {
00208       error (0, 0, "pthread_setcanceltype after 2nd creat returned invalid value %d",
00209             old);
00210       ret = 1;
00211     }
00212 
00213   clobber_lots_of_regs ();
00214   open (fname, O_CREAT, 0400);
00215 
00216   rc = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &old);
00217   if (rc)
00218     {
00219       error (0, rc, "pthread_setcanceltype after open failed");
00220       ret = 1;
00221     }
00222   if (old != PTHREAD_CANCEL_DEFERRED)
00223     {
00224       error (0, 0, "pthread_setcanceltype after open returned invalid value %d",
00225             old);
00226       ret = 1;
00227     }
00228 
00229   clobber_lots_of_regs ();
00230   open (fname, O_CREAT, 0400);
00231 
00232   rc = pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &old);
00233   if (rc)
00234     {
00235       error (0, rc, "pthread_setcanceltype after 2nd open failed");
00236       ret = 1;
00237     }
00238   if (old != PTHREAD_CANCEL_ASYNCHRONOUS)
00239     {
00240       error (0, 0, "pthread_setcanceltype after 2nd open returned invalid value %d",
00241             old);
00242       ret = 1;
00243     }
00244 
00245   *enddir = '\0';
00246   rmdir (fname);
00247 
00248   clobber_lots_of_regs ();
00249   select (-1, NULL, NULL, NULL, NULL);
00250 
00251   rc = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &old);
00252   if (rc)
00253     {
00254       error (0, rc, "pthread_setcanceltype after select failed");
00255       ret = 1;
00256     }
00257   if (old != PTHREAD_CANCEL_DEFERRED)
00258     {
00259       error (0, 0, "pthread_setcanceltype after select returned invalid value %d",
00260             old);
00261       ret = 1;
00262     }
00263 
00264   clobber_lots_of_regs ();
00265   select (-1, NULL, NULL, NULL, NULL);
00266 
00267   rc = pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &old);
00268   if (rc)
00269     {
00270       error (0, rc, "pthread_setcanceltype after 2nd select failed");
00271       ret = 1;
00272     }
00273   if (old != PTHREAD_CANCEL_ASYNCHRONOUS)
00274     {
00275       error (0, 0, "pthread_setcanceltype after 2nd select returned invalid value %d",
00276             old);
00277       ret = 1;
00278     }
00279 
00280   pthread_join (th, NULL);
00281 
00282   return ret;
00283 }
00284 
00285 #define TIMEOUT 20
00286 #define TEST_FUNCTION do_test ()
00287 #include "../test-skeleton.c"