]>
Commit | Line | Data |
---|---|---|
6d7e8eda | 1 | /* Copyright (C) 2002-2023 Free Software Foundation, Inc. |
b74121ae | 2 | This file is part of the GNU C Library. |
b74121ae UD |
3 | |
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. | |
8 | ||
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. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 | 15 | License along with the GNU C Library; if not, see |
5a82c748 | 16 | <https://www.gnu.org/licenses/>. */ |
b74121ae UD |
17 | |
18 | #include <errno.h> | |
19 | #include <fcntl.h> | |
6f4973c1 | 20 | #include <getopt.h> |
b74121ae | 21 | #include <signal.h> |
b74121ae | 22 | #include <stdlib.h> |
6f4973c1 AZ |
23 | #include <semaphore.h> |
24 | #include <sys/mman.h> | |
25 | ||
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> | |
c23de0aa | 31 | #include <support/xthread.h> |
b74121ae | 32 | |
6f4973c1 AZ |
33 | static const char *command; |
34 | static const char *pidfile; | |
35 | static const char *semfile; | |
36 | static char *pidfilename; | |
37 | static char *semfilename; | |
38 | ||
39 | static sem_t *sem; | |
b74121ae UD |
40 | |
41 | static void * | |
42 | tf (void *arg) | |
43 | { | |
6f4973c1 AZ |
44 | char *cmd = xasprintf ("%s --direct --sem %s --pidfile %s", |
45 | command, semfilename, pidfilename); | |
b74121ae UD |
46 | system (cmd); |
47 | /* This call should never return. */ | |
48 | return NULL; | |
49 | } | |
50 | ||
b74121ae UD |
51 | static void |
52 | sl (void) | |
53 | { | |
6f4973c1 | 54 | FILE *f = xfopen (pidfile, "w"); |
b74121ae UD |
55 | |
56 | fprintf (f, "%lld\n", (long long) getpid ()); | |
57 | fflush (f); | |
58 | ||
6f4973c1 AZ |
59 | if (sem_post (sem) != 0) |
60 | FAIL_EXIT1 ("sem_post: %m"); | |
61 | ||
b74121ae UD |
62 | struct flock fl = |
63 | { | |
64 | .l_type = F_WRLCK, | |
65 | .l_start = 0, | |
66 | .l_whence = SEEK_SET, | |
67 | .l_len = 1 | |
68 | }; | |
69 | if (fcntl (fileno (f), F_SETLK, &fl) != 0) | |
6f4973c1 | 70 | FAIL_EXIT1 ("fcntl (F_SETFL): %m"); |
b74121ae UD |
71 | |
72 | sigset_t ss; | |
73 | sigfillset (&ss); | |
74 | sigsuspend (&ss); | |
75 | exit (0); | |
76 | } | |
77 | ||
78 | ||
79 | static void | |
80 | do_prepare (int argc, char *argv[]) | |
81 | { | |
6f4973c1 AZ |
82 | int semfd; |
83 | if (semfile == NULL) | |
84 | semfd = create_temp_file ("tst-cancel7.", &semfilename); | |
85 | else | |
86 | semfd = open (semfile, O_RDWR); | |
87 | TEST_VERIFY_EXIT (semfd != -1); | |
88 | ||
89 | sem = xmmap (NULL, sizeof (sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, | |
90 | semfd); | |
91 | TEST_VERIFY_EXIT (sem != SEM_FAILED); | |
92 | if (semfile == NULL) | |
93 | { | |
94 | xftruncate (semfd, sizeof (sem_t)); | |
95 | TEST_VERIFY_EXIT (sem_init (sem, 1, 0) != -1); | |
96 | } | |
97 | ||
b74121ae UD |
98 | if (command == NULL) |
99 | command = argv[0]; | |
100 | ||
101 | if (pidfile) | |
102 | sl (); | |
103 | ||
6f4973c1 | 104 | int fd = create_temp_file ("tst-cancel7-pid-", &pidfilename); |
b74121ae | 105 | if (fd == -1) |
6f4973c1 | 106 | FAIL_EXIT1 ("create_temp_file failed: %m"); |
b74121ae | 107 | |
6f4973c1 AZ |
108 | xwrite (fd, " ", 1); |
109 | xclose (fd); | |
b74121ae UD |
110 | } |
111 | ||
112 | ||
113 | static int | |
114 | do_test (void) | |
115 | { | |
6f4973c1 | 116 | pthread_t th = xpthread_create (NULL, tf, NULL); |
b74121ae | 117 | |
06acd6d1 SH |
118 | /* Wait to cancel until after the pid is written. */ |
119 | if (sem_wait (sem) != 0) | |
120 | FAIL_EXIT1 ("sem_wait: %m"); | |
b74121ae | 121 | |
c23de0aa FW |
122 | xpthread_cancel (th); |
123 | void *r = xpthread_join (th); | |
b74121ae | 124 | |
6f4973c1 | 125 | FILE *f = xfopen (pidfilename, "r+"); |
b74121ae UD |
126 | |
127 | long long ll; | |
128 | if (fscanf (f, "%lld\n", &ll) != 1) | |
6f4973c1 | 129 | FAIL_EXIT1 ("fscanf: %m"); |
b74121ae UD |
130 | |
131 | struct flock fl = | |
132 | { | |
133 | .l_type = F_WRLCK, | |
134 | .l_start = 0, | |
135 | .l_whence = SEEK_SET, | |
136 | .l_len = 1 | |
137 | }; | |
138 | if (fcntl (fileno (f), F_GETLK, &fl) != 0) | |
6f4973c1 | 139 | FAIL_EXIT1 ("fcntl: %m"); |
b74121ae UD |
140 | |
141 | if (fl.l_type != F_UNLCK) | |
142 | { | |
143 | printf ("child %lld still running\n", (long long) fl.l_pid); | |
144 | if (fl.l_pid == ll) | |
145 | kill (fl.l_pid, SIGKILL); | |
146 | ||
b74121ae UD |
147 | return 1; |
148 | } | |
149 | ||
6f4973c1 | 150 | xfclose (f); |
b74121ae UD |
151 | |
152 | return r != PTHREAD_CANCELED; | |
153 | } | |
154 | ||
155 | static void | |
156 | do_cleanup (void) | |
157 | { | |
158 | FILE *f = fopen (pidfilename, "r+"); | |
159 | long long ll; | |
160 | ||
161 | if (f != NULL && fscanf (f, "%lld\n", &ll) == 1) | |
162 | { | |
163 | struct flock fl = | |
164 | { | |
165 | .l_type = F_WRLCK, | |
166 | .l_start = 0, | |
167 | .l_whence = SEEK_SET, | |
168 | .l_len = 1 | |
169 | }; | |
170 | if (fcntl (fileno (f), F_GETLK, &fl) == 0 && fl.l_type != F_UNLCK | |
171 | && fl.l_pid == ll) | |
172 | kill (fl.l_pid, SIGKILL); | |
173 | ||
174 | fclose (f); | |
175 | } | |
b74121ae UD |
176 | } |
177 | ||
178 | #define OPT_COMMAND 10000 | |
179 | #define OPT_PIDFILE 10001 | |
6f4973c1 | 180 | #define OPT_SEMFILE 10002 |
b74121ae UD |
181 | #define CMDLINE_OPTIONS \ |
182 | { "command", required_argument, NULL, OPT_COMMAND }, \ | |
6f4973c1 AZ |
183 | { "pidfile", required_argument, NULL, OPT_PIDFILE }, \ |
184 | { "sem", required_argument, NULL, OPT_SEMFILE }, | |
c23de0aa FW |
185 | static void |
186 | cmdline_process (int c) | |
187 | { | |
188 | switch (c) | |
189 | { | |
f38aee21 | 190 | case OPT_COMMAND: |
c23de0aa FW |
191 | command = optarg; |
192 | break; | |
193 | case OPT_PIDFILE: | |
194 | pidfile = optarg; | |
195 | break; | |
6f4973c1 AZ |
196 | case OPT_SEMFILE: |
197 | semfile = optarg; | |
198 | break; | |
c23de0aa FW |
199 | } |
200 | } | |
201 | #define CMDLINE_PROCESS cmdline_process | |
202 | #define CLEANUP_HANDLER do_cleanup | |
203 | #define PREPARE do_prepare | |
c23de0aa | 204 | #include <support/test-driver.c> |