(cleanup): Add a lseek call before the write.
[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 static void *
29 t1 (void *arg)
30 {
31   pthread_cleanup_push (cleanup, (void *) (long int) 1);
32   return NULL;
33   pthread_cleanup_pop (0);
34 }
35
36
37 static void
38 inner (int a)
39 {
40   pthread_cleanup_push (cleanup, (void *) (long int) a);
41   if (a)
42     return;
43   pthread_cleanup_pop (0);
44 }
45
46
47 static void *
48 t2 (void *arg)
49 {
50   pthread_cleanup_push (cleanup, (void *) (long int) 2);
51   inner ((int) (long int) arg);
52   return NULL;
53   pthread_cleanup_pop (0);
54 }
55
56
57 static void *
58 t3 (void *arg)
59 {
60   pthread_cleanup_push (cleanup, (void *) (long int) 4);
61   inner ((int) (long int) arg);
62   pthread_exit (NULL);
63   pthread_cleanup_pop (0);
64 }
65
66
67 int
68 main (void)
69 {
70   pthread_t td;
71   int err;
72   char tmp[] = "thtstXXXXXX";
73   struct stat64 st;
74   int result = 0;
75
76   fd = mkstemp (tmp);
77   if (fd == -1)
78     {
79       printf ("cannot create temporary file: %m");
80       exit (1);
81     }
82   unlink (tmp);
83
84   err = pthread_barrier_init (&bar, NULL, 2);
85   if (err != 0 )
86     {
87       printf ("cannot create barrier: %s\n", strerror (err));
88       exit (1);
89     }
90
91   err = pthread_create (&td, NULL, t1, NULL);
92   if (err != 0)
93     {
94       printf ("cannot create thread t1: %s\n", strerror (err));
95       exit (1);
96     }
97
98   err = pthread_join (td, NULL);
99   if (err != 0)
100     {
101       printf ("cannot join thread: %s\n", strerror (err));
102       exit (1);
103     }
104
105   err = pthread_create (&td, NULL, t2, (void *) 3);
106   if (err != 0)
107     {
108       printf ("cannot create thread t2: %s\n", strerror (err));
109       exit (1);
110     }
111
112   err = pthread_join (td, NULL);
113   if (err != 0)
114     {
115       printf ("cannot join thread: %s\n", strerror (err));
116       exit (1);
117     }
118
119   err = pthread_create (&td, NULL, t3, (void *) 5);
120   if (err != 0)
121     {
122       printf ("cannot create thread t3: %s\n", strerror (err));
123       exit (1);
124     }
125
126   err = pthread_join (td, NULL);
127   if (err != 0)
128     {
129       printf ("cannot join thread: %s\n", strerror (err));
130       exit (1);
131     }
132
133   if (fstat64 (fd, &st) < 0)
134     {
135       printf ("cannot stat temporary file: %m\n");
136       result = 1;
137     }
138   else if (st.st_size != 0)
139     {
140       char buf[512];
141       puts ("some cleanup handlers ran:");
142       fflush (stdout);
143       while (1)
144         {
145           ssize_t n = read (fd, buf, sizeof buf);
146           if (n <= 0)
147             break;
148           write (STDOUT_FILENO, buf, n);
149         }
150       result = 1;
151     }
152
153   return result;
154 }