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

Reply via email to