1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-24 20:30:28 +02:00

'primitive-fork' closes and recreates the current thread's 'sleep_pipe'.

Partly fixes <https://bugs.gnu.org/41948>.

Previously, the child process could end up using the same 'sleep_pipe'
as its parent, leading to a race condition handling signals.

* libguile/posix.c (do_fork): New function.
(scm_fork): Call 'do_fork' via 'scm_without_guile'.
* test-suite/standalone/test-signal-fork: New test.
* test-suite/standalone/Makefile.am (check_SCRIPTS, TESTS): Add it.
This commit is contained in:
Ludovic Courtès 2021-05-08 21:39:15 +02:00
parent 5a281e35f4
commit 381291f5ff
3 changed files with 94 additions and 1 deletions

View file

@ -1217,6 +1217,31 @@ SCM_DEFINE (scm_execle, "execle", 2, 0, 1,
#undef FUNC_NAME
#ifdef HAVE_FORK
/* Create a process and perform post-fork cleanups in the child. */
static void *
do_fork (void *ret)
{
pid_t pid = fork ();
if (pid == 0)
{
/* The child process must not share its sleep pipe with the
parent. Close it and create a new one. */
int err;
scm_thread *t = SCM_I_CURRENT_THREAD;
close (t->sleep_pipe[0]);
close (t->sleep_pipe[1]);
err = pipe2 (t->sleep_pipe, O_CLOEXEC);
if (err != 0)
abort ();
}
* (pid_t *) ret = pid;
return NULL;
}
SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
(),
"Creates a new \"child\" process by duplicating the current \"parent\" process.\n"
@ -1244,7 +1269,9 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
" further behavior unspecified. See \"Processes\" in the\n"
" manual, for more information.\n"),
scm_current_warning_port ());
pid = fork ();
scm_without_guile (do_fork, &pid);
if (pid == -1)
SCM_SYSERROR;
return scm_from_int (pid);