[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