Hi Corinna,

On 7/30/2020 1:17 PM, Corinna Vinschen wrote:
Hi Ken,

On Jul 30 13:59, Corinna Vinschen wrote:
On Jul 29 19:12, Ken Brown via Cygwin wrote:
On 7/29/2020 4:17 PM, Ken Brown via Cygwin wrote:
posix_spawn(p) returns before the spawned process is fully up and
running.  [...]
I just took a look at the source, and I see that posix_spawn was taken from
FreeBSD.  Does FreeBSD have the same problem?  Should applications just be
aware of this issue and insert a sleep after posix_spawn before sending
signals?

Actually, this is a Cygwin problem.  I just had a look into the
newlib implementation myself, and it turns out that the code,
in particular the do_posix_spawn() function, is BSD specific.  It
relies on the BSD implementation of vfork(2).  Cygwin's vfork(2)
on the other hand, is NOT following the historic idea of the
BSD vfork(2), rather it's equivalent to fork(2).  This is
POSIX compliant, but certainly the reliance of the BSD vfork
behaviour makes do_posix_spawn() as it's implemented right now,
not overly functional for Cygwin.

IOW, we need a Cygwin-specific do_posix_spawn() using fork(2)
in conjunction with some synchronization the BSD function
gets "for free" by using its specific vfork(2).

Below is a POC implementation for a Cygwin-specific do_posix_spawn().
If this does the trick (at least your testcase works in my testing),
then I'm planning to move the function over to the winsup/cygwin dir
so it can be streamlined further.

Can you give it a try?

It looks like something further is needed: 'wait' doesn't seem to recognize the spawned process.

I'm attaching a second test case. This spawns a "sleep 10" process and then waits for termination. If I run it on Cygwin, it returns immediately like this:

  $ ./spawn_test2
  wait: No child processes
  sleep 10 exited normally with status 0

and the sleep process is still running.  If I run it on Linux, I see

  $ ./spawn_test2
  sleep 10 exited normally with status 0

if I let the sleep process run to completion, or

  $ ./spawn_test2
  sleep 10 exited due to signal 15

if I run 'pkill sleep' in another terminal.

Ken
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <spawn.h>
#include <signal.h>
#include <sys/wait.h>

extern char **environ;

pid_t
run_sleep ()
{
  pid_t pid;
  char *argv[] = { "sleep", "10", NULL };
  int err = posix_spawnp (&pid, "/bin/sleep", NULL, NULL, argv, environ);
  if (err == 0)
    return pid;
  else
    {
      printf ("posix_spawnp: %s\n", strerror (err));
      exit (1);
    }
}

int
main ()
{
  int status;
  pid_t pid = run_sleep ();
  if (wait (&status) < 0)
    perror ("wait");
  if (WIFEXITED (status))
    printf ("sleep 10 exited normally with status %d\n", WEXITSTATUS (status));
  else if (WIFSIGNALED (status))
    printf ("sleep 10 exited due to signal %d\n", WTERMSIG (status));
  else
    printf ("????\n");
}
--
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to