I've run into an odd issue with exec and kill in winsup/testsuite that doesn't happen in a more normal configuration. What I'm doing is getting the pid via getpid (), then forking. In the forked child, I can call kill (pid, SIGUSR1) without issue, but if instead I call execv (passing the pid as an argument) and then call kill after the exec I get "No such process" error. Can anyone tell what I'm doing wrong?
Here's the test output: kill after exec: No such process SUCCESS: The process with PID 3748 (child process of PID 5984) has been terminated. Timeout FAIL winsup.api/killissue.exe (exit status: 124) And here's a test with the working fork/kill if 0'ed out and the broken fork/exec/kill in place: Subject: [RFC PATCH] Cygwin: testsuite: test odd issue with kill kill of parent pid works in forked child, but not after exec? Only in testsuite though. Signed-off-by: Jeremy Drake <cyg...@jdrake.com> --- winsup/testsuite/Makefile.am | 1 + winsup/testsuite/winsup.api/killissue.c | 117 ++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 winsup/testsuite/winsup.api/killissue.c diff --git a/winsup/testsuite/Makefile.am b/winsup/testsuite/Makefile.am index 20e06b9c51..b3c30be181 100644 --- a/winsup/testsuite/Makefile.am +++ b/winsup/testsuite/Makefile.am @@ -37,6 +37,7 @@ check_PROGRAMS = \ winsup.api/devdsp \ winsup.api/devzero \ winsup.api/iospeed \ + winsup.api/killissue \ winsup.api/mmaptest01 \ winsup.api/mmaptest02 \ winsup.api/mmaptest03 \ diff --git a/winsup/testsuite/winsup.api/killissue.c b/winsup/testsuite/winsup.api/killissue.c new file mode 100644 index 0000000000..c5b397f090 --- /dev/null +++ b/winsup/testsuite/winsup.api/killissue.c @@ -0,0 +1,117 @@ +#define _GNU_SOURCE +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/wait.h> +#include <unistd.h> + +int main (int argc, char **argv) +{ + sigset_t set, oldset; + int ret = 0, status; + pid_t pid, childpid; + + if (argc == 3 && !strcmp (argv[1], "--child")) + { + if (kill (atoi (argv[2]), SIGUSR1) == -1) + { + perror ("kill after exec"); + return 1; + } + + usleep (100000); + return 0; + } + + pid = getpid (); + + sigemptyset (&set); + sigaddset (&set, SIGUSR1); + errno = 0; + sigprocmask (SIG_BLOCK, &set, &oldset); + +#if 0 + switch ((childpid = fork ())) + { + case -1: + perror ("fork"); + ret |= 1; + break; + case 0: + /* child */ + if (kill (pid, SIGUSR1) == -1) + { + perror ("kill without exec"); + return 1; + } + return 0; + default: + /* parent */ + while (1) + { + int sig; + if (sigwait (&set, &sig)) + { + perror ("sigwait"); + return 2; + } + if (sig == SIGUSR1) + break; + } + if (waitpid (childpid, &status, 0) == -1) + { + perror ("waitpid"); + ret |= 1; + } + else if (WIFEXITED (status)) + ret |= WEXITSTATUS (status); + else if (WIFSIGNALED (status)) + ret |= WTERMSIG (status); + } +#endif + + switch ((childpid = fork ())) + { + case -1: + perror ("fork"); + ret |= 1; + break; + case 0: + /* child */ + { + char buf[16]; + char *childargs[] = {"/proc/self/exe", "--child", buf, NULL}; + sprintf (buf, "%d", pid); + execv (childargs[0], childargs); + perror ("execv"); + } + return 1; + default: + /* parent */ + while (1) + { + int sig; + if (sigwait (&set, &sig)) + { + perror ("sigwait"); + return 2; + } + if (sig == SIGUSR1) + break; + } + if (waitpid (childpid, &status, 0) == -1) + { + perror ("waitpid"); + ret |= 1; + } + else if (WIFEXITED (status)) + ret |= WEXITSTATUS (status); + else if (WIFSIGNALED (status)) + ret |= WTERMSIG (status); + } + sigprocmask (SIG_SETMASK, &oldset, NULL); + + return ret; +} -- 2.50.1.windows.1