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/>. */
23 #include <semaphore.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
;
41 static void do_cleanup (void);
46 char *cmd
= xasprintf ("%s --direct --sem %s --pidfile %s",
47 command
, semfilename
, pidfilename
);
49 FAIL_EXIT1("system call unexpectedly returned");
50 /* This call should never return. */
57 FILE *f
= xfopen (pidfile
, "w");
59 fprintf (f
, "%lld\n", (long long) getpid ());
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");
83 do_prepare (int argc
, char *argv
[])
87 semfd
= create_temp_file ("tst-cancel7.", &semfilename
);
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
,
94 TEST_VERIFY_EXIT (sem
!= SEM_FAILED
);
97 xftruncate (semfd
, sizeof (sem_t
));
98 TEST_VERIFY_EXIT (sem_init (sem
, 1, 0) != -1);
107 int fd
= create_temp_file ("tst-cancel7-pid-", &pidfilename
);
109 FAIL_EXIT1 ("create_temp_file failed: %m");
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+");
133 if (fscanf (f
, "%lld\n", &ll
) != 1)
134 FAIL_EXIT1 ("fscanf: %m");
140 .l_whence
= SEEK_SET
,
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
);
150 kill (fl
.l_pid
, SIGKILL
);
157 return r
!= PTHREAD_CANCELED
;
163 FILE *f
= fopen (pidfilename
, "r+");
166 if (f
!= NULL
&& fscanf (f
, "%lld\n", &ll
) == 1)
172 .l_whence
= SEEK_SET
,
175 if (fcntl (fileno (f
), F_GETLK
, &fl
) == 0 && fl
.l_type
!= F_UNLCK
177 kill (fl
.l_pid
, SIGKILL
);
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 },
191 cmdline_process (int c
)
206 #define CMDLINE_PROCESS cmdline_process
207 #define CLEANUP_HANDLER do_cleanup
208 #define PREPARE do_prepare
209 #include <support/test-driver.c>