@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007,
-@c 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+@c 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@node POSIX
In the child the return value is 0. In the parent the return value is
the integer process ID of the child.
+Note that it is unsafe to fork a process that has multiple threads
+running, as only the thread that calls @code{primitive-fork} will
+persist in the child. Any resources that other threads held, such as
+locked mutexes or open file descriptors, are lost. Indeed, @acronym{POSIX}
+specifies that only async-signal-safe procedures are safe to call after
+a multithreaded fork, which is a very limited set. Guile issues a
+warning if it detects a fork from a multi-threaded program.
+
+If you are going to @code{exec} soon after forking, the procedures in
+@code{(ice-9 popen)} may be useful to you, as they fork and exec within
+an async-signal-safe function carefully written to ensure robust program
+behavior, even in the presence of threads. @xref{Pipes}, for more.
+
This procedure has been renamed from @code{fork} to avoid a naming conflict
with the scsh fork.
@end deffn
#define FUNC_NAME s_scm_fork
{
int pid;
+ if (scm_ilength (scm_all_threads ()) != 1)
+ /* Other threads may be holding on to resources that Guile needs --
+ it is not safe to permit one thread to fork while others are
+ running.
+
+ In addition, POSIX clearly specifies that if a multi-threaded
+ program forks, the child must only call functions that are
+ async-signal-safe. We can't guarantee that in general. The best
+ we can do is to allow forking only very early, before any call to
+ sigaction spawns the signal-handling thread. */
+ scm_display
+ (scm_from_latin1_string
+ ("warning: call to primitive-fork while multiple threads are running;\n"
+ " further behavior unspecified. See \"Processes\" in the\n"
+ " manual, for more information.\n"),
+ scm_current_warning_port ());
pid = fork ();
if (pid == -1)
SCM_SYSERROR;