1 /* Copyright (C) 2002-2022 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
;
44 char *cmd
= xasprintf ("%s --direct --sem %s --pidfile %s",
45 command
, semfilename
, pidfilename
);
47 /* This call should never return. */
54 FILE *f
= xfopen (pidfile
, "w");
56 fprintf (f
, "%lld\n", (long long) getpid ());
59 if (sem_post (sem
) != 0)
60 FAIL_EXIT1 ("sem_post: %m");
69 if (fcntl (fileno (f
), F_SETLK
, &fl
) != 0)
70 FAIL_EXIT1 ("fcntl (F_SETFL): %m");
80 do_prepare (int argc
, char *argv
[])
84 semfd
= create_temp_file ("tst-cancel7.", &semfilename
);
86 semfd
= open (semfile
, O_RDWR
);
87 TEST_VERIFY_EXIT (semfd
!= -1);
89 sem
= xmmap (NULL
, sizeof (sem_t
), PROT_READ
| PROT_WRITE
, MAP_SHARED
,
91 TEST_VERIFY_EXIT (sem
!= SEM_FAILED
);
94 xftruncate (semfd
, sizeof (sem_t
));
95 TEST_VERIFY_EXIT (sem_init (sem
, 1, 0) != -1);
104 int fd
= create_temp_file ("tst-cancel7-pid-", &pidfilename
);
106 FAIL_EXIT1 ("create_temp_file failed: %m");
116 pthread_t th
= xpthread_create (NULL
, tf
, NULL
);
118 /* Wait to cancel until after the pid is written. */
119 if (sem_wait (sem
) != 0)
120 FAIL_EXIT1 ("sem_wait: %m");
122 xpthread_cancel (th
);
123 void *r
= xpthread_join (th
);
125 FILE *f
= xfopen (pidfilename
, "r+");
128 if (fscanf (f
, "%lld\n", &ll
) != 1)
129 FAIL_EXIT1 ("fscanf: %m");
135 .l_whence
= SEEK_SET
,
138 if (fcntl (fileno (f
), F_GETLK
, &fl
) != 0)
139 FAIL_EXIT1 ("fcntl: %m");
141 if (fl
.l_type
!= F_UNLCK
)
143 printf ("child %lld still running\n", (long long) fl
.l_pid
);
145 kill (fl
.l_pid
, SIGKILL
);
152 return r
!= PTHREAD_CANCELED
;
158 FILE *f
= fopen (pidfilename
, "r+");
161 if (f
!= NULL
&& fscanf (f
, "%lld\n", &ll
) == 1)
167 .l_whence
= SEEK_SET
,
170 if (fcntl (fileno (f
), F_GETLK
, &fl
) == 0 && fl
.l_type
!= F_UNLCK
172 kill (fl
.l_pid
, SIGKILL
);
178 #define OPT_COMMAND 10000
179 #define OPT_PIDFILE 10001
180 #define OPT_SEMFILE 10002
181 #define CMDLINE_OPTIONS \
182 { "command", required_argument, NULL, OPT_COMMAND }, \
183 { "pidfile", required_argument, NULL, OPT_PIDFILE }, \
184 { "sem", required_argument, NULL, OPT_SEMFILE },
186 cmdline_process (int c
)
201 #define CMDLINE_PROCESS cmdline_process
202 #define CLEANUP_HANDLER do_cleanup
203 #define PREPARE do_prepare
204 #include <support/test-driver.c>