added license for sysdeps/ieee754/flt-32/e_gammaf_r.c
[glibc.git] / nptl / tst-cancel7.c
blob3f874c2a3c24c6a58ff64c99a73571e09a895405
1 /* Copyright (C) 2002-2024 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <getopt.h>
21 #include <signal.h>
22 #include <stdlib.h>
23 #include <semaphore.h>
24 #include <sys/mman.h>
26 #include <support/check.h>
27 #include <support/support.h>
28 #include <support/temp_file.h>
29 #include <support/xstdio.h>
30 #include <support/xunistd.h>
31 #include <support/xthread.h>
33 static const char *command;
34 static const char *pidfile;
35 static const char *semfile;
36 static char *pidfilename;
37 static char *semfilename;
39 static sem_t *sem;
41 static void do_cleanup (void);
43 static void *
44 tf (void *arg)
46 char *cmd = xasprintf ("%s --direct --sem %s --pidfile %s",
47 command, semfilename, pidfilename);
48 if (system (cmd))
49 FAIL_EXIT1("system call unexpectedly returned");
50 /* This call should never return. */
51 return NULL;
54 static void
55 sl (void)
57 FILE *f = xfopen (pidfile, "w");
59 fprintf (f, "%lld\n", (long long) getpid ());
60 fflush (f);
62 struct flock fl =
64 .l_type = F_WRLCK,
65 .l_start = 0,
66 .l_whence = SEEK_SET,
67 .l_len = 1
69 if (fcntl (fileno (f), F_SETLK, &fl) != 0)
70 FAIL_EXIT1 ("fcntl (F_SETFL): %m");
72 if (sem_post (sem) != 0)
73 FAIL_EXIT1 ("sem_post: %m");
75 sigset_t ss;
76 sigfillset (&ss);
77 sigsuspend (&ss);
78 exit (0);
82 static void
83 do_prepare (int argc, char *argv[])
85 int semfd;
86 if (semfile == NULL)
87 semfd = create_temp_file ("tst-cancel7.", &semfilename);
88 else
89 semfd = open (semfile, O_RDWR);
90 TEST_VERIFY_EXIT (semfd != -1);
92 sem = xmmap (NULL, sizeof (sem_t), PROT_READ | PROT_WRITE, MAP_SHARED,
93 semfd);
94 TEST_VERIFY_EXIT (sem != SEM_FAILED);
95 if (semfile == NULL)
97 xftruncate (semfd, sizeof (sem_t));
98 TEST_VERIFY_EXIT (sem_init (sem, 1, 0) != -1);
101 if (command == NULL)
102 command = argv[0];
104 if (pidfile)
105 sl ();
107 int fd = create_temp_file ("tst-cancel7-pid-", &pidfilename);
108 if (fd == -1)
109 FAIL_EXIT1 ("create_temp_file failed: %m");
111 xwrite (fd, " ", 1);
112 xclose (fd);
114 atexit (do_cleanup);
118 static int
119 do_test (void)
121 pthread_t th = xpthread_create (NULL, tf, NULL);
123 /* Wait to cancel until after the pid is written and file locked. */
124 if (sem_wait (sem) != 0)
125 FAIL_EXIT1 ("sem_wait: %m");
127 xpthread_cancel (th);
128 void *r = xpthread_join (th);
130 FILE *f = xfopen (pidfilename, "r+");
132 long long ll;
133 if (fscanf (f, "%lld\n", &ll) != 1)
134 FAIL_EXIT1 ("fscanf: %m");
136 struct flock fl =
138 .l_type = F_WRLCK,
139 .l_start = 0,
140 .l_whence = SEEK_SET,
141 .l_len = 1
143 if (fcntl (fileno (f), F_GETLK, &fl) != 0)
144 FAIL_EXIT1 ("fcntl: %m");
146 if (fl.l_type != F_UNLCK)
148 printf ("child %lld still running\n", (long long) fl.l_pid);
149 if (fl.l_pid == ll)
150 kill (fl.l_pid, SIGKILL);
152 return 1;
155 xfclose (f);
157 return r != PTHREAD_CANCELED;
160 static void
161 do_cleanup (void)
163 FILE *f = fopen (pidfilename, "r+");
164 long long ll;
166 if (f != NULL && fscanf (f, "%lld\n", &ll) == 1)
168 struct flock fl =
170 .l_type = F_WRLCK,
171 .l_start = 0,
172 .l_whence = SEEK_SET,
173 .l_len = 1
175 if (fcntl (fileno (f), F_GETLK, &fl) == 0 && fl.l_type != F_UNLCK
176 && fl.l_pid == ll)
177 kill (fl.l_pid, SIGKILL);
179 fclose (f);
183 #define OPT_COMMAND 10000
184 #define OPT_PIDFILE 10001
185 #define OPT_SEMFILE 10002
186 #define CMDLINE_OPTIONS \
187 { "command", required_argument, NULL, OPT_COMMAND }, \
188 { "pidfile", required_argument, NULL, OPT_PIDFILE }, \
189 { "sem", required_argument, NULL, OPT_SEMFILE },
190 static void
191 cmdline_process (int c)
193 switch (c)
195 case OPT_COMMAND:
196 command = optarg;
197 break;
198 case OPT_PIDFILE:
199 pidfile = optarg;
200 break;
201 case OPT_SEMFILE:
202 semfile = optarg;
203 break;
206 #define CMDLINE_PROCESS cmdline_process
207 #define CLEANUP_HANDLER do_cleanup
208 #define PREPARE do_prepare
209 #include <support/test-driver.c>