1 /* Copyright (C) 2002-2023 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 FAIL_EXIT1("system call unexpectedly returned");
48 /* This call should never return. */
55 FILE *f
= xfopen (pidfile
, "w");
57 fprintf (f
, "%lld\n", (long long) getpid ());
60 if (sem_post (sem
) != 0)
61 FAIL_EXIT1 ("sem_post: %m");
70 if (fcntl (fileno (f
), F_SETLK
, &fl
) != 0)
71 FAIL_EXIT1 ("fcntl (F_SETFL): %m");
81 do_prepare (int argc
, char *argv
[])
85 semfd
= create_temp_file ("tst-cancel7.", &semfilename
);
87 semfd
= open (semfile
, O_RDWR
);
88 TEST_VERIFY_EXIT (semfd
!= -1);
90 sem
= xmmap (NULL
, sizeof (sem_t
), PROT_READ
| PROT_WRITE
, MAP_SHARED
,
92 TEST_VERIFY_EXIT (sem
!= SEM_FAILED
);
95 xftruncate (semfd
, sizeof (sem_t
));
96 TEST_VERIFY_EXIT (sem_init (sem
, 1, 0) != -1);
105 int fd
= create_temp_file ("tst-cancel7-pid-", &pidfilename
);
107 FAIL_EXIT1 ("create_temp_file failed: %m");
117 pthread_t th
= xpthread_create (NULL
, tf
, NULL
);
119 /* Wait to cancel until after the pid is written. */
120 if (sem_wait (sem
) != 0)
121 FAIL_EXIT1 ("sem_wait: %m");
123 xpthread_cancel (th
);
124 void *r
= xpthread_join (th
);
126 FILE *f
= xfopen (pidfilename
, "r+");
129 if (fscanf (f
, "%lld\n", &ll
) != 1)
130 FAIL_EXIT1 ("fscanf: %m");
136 .l_whence
= SEEK_SET
,
139 if (fcntl (fileno (f
), F_GETLK
, &fl
) != 0)
140 FAIL_EXIT1 ("fcntl: %m");
142 if (fl
.l_type
!= F_UNLCK
)
144 printf ("child %lld still running\n", (long long) fl
.l_pid
);
146 kill (fl
.l_pid
, SIGKILL
);
153 return r
!= PTHREAD_CANCELED
;
159 FILE *f
= fopen (pidfilename
, "r+");
162 if (f
!= NULL
&& fscanf (f
, "%lld\n", &ll
) == 1)
168 .l_whence
= SEEK_SET
,
171 if (fcntl (fileno (f
), F_GETLK
, &fl
) == 0 && fl
.l_type
!= F_UNLCK
173 kill (fl
.l_pid
, SIGKILL
);
179 #define OPT_COMMAND 10000
180 #define OPT_PIDFILE 10001
181 #define OPT_SEMFILE 10002
182 #define CMDLINE_OPTIONS \
183 { "command", required_argument, NULL, OPT_COMMAND }, \
184 { "pidfile", required_argument, NULL, OPT_PIDFILE }, \
185 { "sem", required_argument, NULL, OPT_SEMFILE },
187 cmdline_process (int c
)
202 #define CMDLINE_PROCESS cmdline_process
203 #define CLEANUP_HANDLER do_cleanup
204 #define PREPARE do_prepare
205 #include <support/test-driver.c>