84b8197e42db9dcfad9d651e2dccfdf9737fb52a
[kopensolaris-gnu/glibc.git] / linuxthreads / tst-cancel.c
1 /* Tests for cancelation handling.  */
2
3 #include <pthread.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/stat.h>
9
10 int fd;
11
12 pthread_barrier_t bar;
13
14
15 static void
16 cleanup (void *arg)
17 {
18   int nr = (int) (long int) arg;
19   char s[30];
20   char *cp = stpcpy (s, "cleanup ");
21   *cp++ = '0' + nr;
22   *cp++ = '\n';
23   __libc_lseek (fd, 0, SEEK_END);
24   __libc_write (fd, s, cp - s);
25 }
26
27
28 volatile int cleanupokcnt;
29
30 static void
31 cleanupok (void *arg)
32 {
33   ++cleanupokcnt;
34 }
35
36
37 static void *
38 t1 (void *arg)
39 {
40   pthread_cleanup_push (cleanup, (void *) (long int) 1);
41   return NULL;
42   pthread_cleanup_pop (0);
43 }
44
45
46 static void
47 inner (int a)
48 {
49   pthread_cleanup_push (cleanup, (void *) (long int) a);
50   if (a)
51     return;
52   pthread_cleanup_pop (0);
53 }
54
55
56 static void *
57 t2 (void *arg)
58 {
59   pthread_cleanup_push (cleanup, (void *) (long int) 2);
60   inner ((int) (long int) arg);
61   return NULL;
62   pthread_cleanup_pop (0);
63 }
64
65
66 static void
67 innerok (int a)
68 {
69   pthread_cleanup_push (cleanup, (void *) (long int) a);
70   if (a)
71     return;
72   pthread_cleanup_pop (0);
73 }
74
75
76 static void *
77 t3 (void *arg)
78 {
79   pthread_cleanup_push (cleanupok, (void *) (long int) 4);
80   innerok ((int) (long int) arg);
81   pthread_exit (NULL);
82   pthread_cleanup_pop (0);
83 }
84
85
86 int
87 main (int argc, char *argv[])
88 {
89   pthread_t td;
90   int err;
91   char *tmp;
92   const char *path;
93   const char template[] = "thtstXXXXXX";
94   struct stat64 st;
95   int result = 0;
96
97   path = argc > 1 ? argv[1] : "";
98   tmp = (char *) alloca (strlen (path) + sizeof template);
99   strcpy (stpcpy (tmp, path), template);
100
101   fd = mkstemp (tmp);
102   if (fd == -1)
103     {
104       printf ("cannot create temporary file: %m");
105       exit (1);
106     }
107   unlink (tmp);
108
109   err = pthread_barrier_init (&bar, NULL, 2);
110   if (err != 0 )
111     {
112       printf ("cannot create barrier: %s\n", strerror (err));
113       exit (1);
114     }
115
116   err = pthread_create (&td, NULL, t1, NULL);
117   if (err != 0)
118     {
119       printf ("cannot create thread t1: %s\n", strerror (err));
120       exit (1);
121     }
122
123   err = pthread_join (td, NULL);
124   if (err != 0)
125     {
126       printf ("cannot join thread: %s\n", strerror (err));
127       exit (1);
128     }
129
130   err = pthread_create (&td, NULL, t2, (void *) 3);
131   if (err != 0)
132     {
133       printf ("cannot create thread t2: %s\n", strerror (err));
134       exit (1);
135     }
136
137   err = pthread_join (td, NULL);
138   if (err != 0)
139     {
140       printf ("cannot join thread: %s\n", strerror (err));
141       exit (1);
142     }
143
144   err = pthread_create (&td, NULL, t3, (void *) 5);
145   if (err != 0)
146     {
147       printf ("cannot create thread t3: %s\n", strerror (err));
148       exit (1);
149     }
150
151   err = pthread_join (td, NULL);
152   if (err != 0)
153     {
154       printf ("cannot join thread: %s\n", strerror (err));
155       exit (1);
156     }
157
158   if (fstat64 (fd, &st) < 0)
159     {
160       printf ("cannot stat temporary file: %m\n");
161       result = 1;
162     }
163   else if (st.st_size != 0)
164     {
165       char buf[512];
166       puts ("some cleanup handlers ran:");
167       fflush (stdout);
168       __lseek (fd, 0, SEEK_SET);
169       while (1)
170         {
171           ssize_t n = read (fd, buf, sizeof buf);
172           if (n <= 0)
173             break;
174           write (STDOUT_FILENO, buf, n);
175         }
176       result = 1;
177     }
178
179   if (cleanupokcnt != 1)
180     {
181       printf ("cleanupokcnt = %d\n", cleanupokcnt);
182       result = 1;
183     }
184
185   return result;
186 }