[PATCH] Cygwin: add _Fork() system call per POSIX.1-2024

Corinna Vinschen corinna-cygwin@cygwin.com
Tue Mar 31 10:07:26 GMT 2026


Hi Jon,

thanks for reviewing!

On Mar 30 21:29, Jon Turney wrote:
> On 30/03/2026 15:41, Corinna Vinschen wrote:
> > From: Corinna Vinschen <corinna@vinschen.de>
> > 
> > The _Fork() function shall be equivalent to fork(), except that fork
> > handlers established by means of the pthread_atfork() function shall
> > not be called and _Fork() shall be async-signal-safe.  Our fork()
> > already is async-signal-safe, so just make sure the pthread_atfork()
> > handlers are not called.
> 
> Nice.
> 
> [...]
> > diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
> > index 48e8b7557d00..82ad3aaf0899 100644
> > --- a/winsup/cygwin/fork.cc
> > +++ b/winsup/cygwin/fork.cc
> > @@ -31,7 +31,7 @@ details. */
> >   /* FIXME: Once things stabilize, bump up to a few minutes.  */
> >   #define FORK_WAIT_TIMEOUT (300 * 1000)     /* 300 seconds */
> > -static int dofork (void **proc, bool *with_forkables);
> > +static int dofork (void **proc, bool is__Fork, bool *with_forkables);
> 
> This looks fine.
> 
> Maybe the new parameter should be named to indicate what extra step it
> enables, rather than what API we're executing? (So, like, do_atfork_handlers
> or something? Or maybe that's less clear)

Actually, I think this is a great idea.  do__Fork is a bit clumsy.  I
renamed the variables to do_atfork_handlers throughout and will push it
with this change in a bit.

> If you have a STC you used to test this you want to share, maybe I can look
> at adding that to testsuite.

Pretty simple:

$ cat > atforktest.c <<EOF
#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int pre = 0;
int pnt = 0;
int chld = 0;

void
prepare (void)
{
  pre = 1;
}

void
parent (void)
{
  pnt = 1;
}

void
child (void)
{
  chld = 1;
}

int
main (int argc, char **argv)
{
  pthread_atfork (prepare, parent, child);

  printf ("Calling %s\n", argc > 1 ? "_Fork()" : "fork()");
  switch (argc > 1 ? _Fork () : fork ())
    {
    case -1:
      printf ("error %d %s\n", errno, strerror (errno));
      return 1;
    case 0:
      printf ("child : prepare %d, parent %d, child %d\n", pre, pnt, chld);
      break;
    default:
      sleep (1);
      printf ("parent: prepare %d, parent %d, child %d\n", pre, pnt, chld);
      break;
    }
  return 0;
}
EOF
$ gcc -g -o atforktest atforktest.c
$ ./atforktest.exe
Calling fork()
child : prepare 1, parent 0, child 1
parent: prepare 1, parent 1, child 0
$ ./atforktest.exe 1
Calling _Fork()
child : prepare 0, parent 0, child 0
parent: prepare 0, parent 0, child 0
$


Thanks,
Corinna


More information about the Cygwin-patches mailing list