[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 01/02: squash! Add 'spawn'.
From: |
Ludovic Courtès |
Subject: |
[Guile-commits] 01/02: squash! Add 'spawn'. |
Date: |
Fri, 13 Jan 2023 09:57:49 -0500 (EST) |
civodul pushed a commit to branch wip-posix-spawn
in repository guile.
commit 354a7e91ef059468c8c31778d73fee2044261f27
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Fri Jan 13 15:37:56 2023 +0100
squash! Add 'spawn'.
* NEWS: Update.
---
NEWS | 15 ++++++++++++++-
doc/ref/posix.texi | 17 +++++++++++------
libguile/posix.c | 20 +++++++++++++-------
3 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/NEWS b/NEWS
index 07011c3c6..b3d31cf89 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,5 @@
Guile NEWS --- history of user-visible changes.
-Copyright (C) 1996-2022 Free Software Foundation, Inc.
+Copyright (C) 1996-2023 Free Software Foundation, Inc.
See the end for copying conditions.
Please send Guile bug reports to bug-guile@gnu.org.
@@ -11,6 +11,19 @@ Changes in 3.0.9 (since 3.0.8)
* New interfaces and functionality
+** New `spawn' procedure to spawn child processes
+
+The new `spawn' procedure creates a child processes executing the given
+program. It lets you control the environment variables of that process
+and redirect its standard input, standard output, and standard error
+streams.
+
+Being implemented in terms of `posix_spawn', it is more portable, more
+robust, and more efficient than the combination of `primitive-fork' and
+`execl'. See "Processes" in the manual for details, and see the 2019
+paper entitled "A fork() in the road" (Andrew Baumann et al.) for
+background information.
+
** `open-file' now supports an "e" flag for O_CLOEXEC
Until now, the high-level `open-file' facility did not provide a way to
diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi
index cb737204f..5653d3758 100644
--- a/doc/ref/posix.texi
+++ b/doc/ref/posix.texi
@@ -2046,10 +2046,14 @@ Guile issues a warning if it detects a fork from a
multi-threaded
program.
@quotation Note
-If you are only looking to fork+exec with some pipes set up, using pipes
-or the more @code{spawn} procedure described below will be more robust
-(in particular in multi-threaded contexts), more portable, and usually
-more efficient.
+If you are looking to spawn a process with some pipes set up, using the
+@code{spawn} procedure described below will be more robust (in
+particular in multi-threaded contexts), more portable, and usually more
+efficient than the combination of @code{primitive-fork} and
+@code{execl}.
+
+@c Recommended reading: ``A fork() in the road'', HotOS 2019,
+@c <https://dx.doi.org/10.1145/3317550.3321435> (paywalled :-/).
@end quotation
This procedure has been renamed from @code{fork} to avoid a naming conflict
@@ -2063,8 +2067,9 @@ with the scsh fork.
[#:error=(current-error-port)] @
[#:search-path?=#t]
Spawn a new child process executing @var{program} with the
-given @var{arguments}, a list of one or more strings, and
-return its PID. Raise a @code{system-error} exception if
+given @var{arguments}, a list of one or more strings (by
+convention, the first argument is typically @var{program}),
+and return its PID. Raise a @code{system-error} exception if
@var{program} could not be found or could not be executed.
If the keyword argument @code{#:search-path?} is true, it
diff --git a/libguile/posix.c b/libguile/posix.c
index 79f96192f..ae9792890 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1420,8 +1420,9 @@ SCM_KEYWORD (kw_search_path, "search-path?");
SCM_DEFINE (scm_spawn_process, "spawn", 2, 0, 1,
(SCM program, SCM arguments, SCM keyword_args),
"Spawn a new child process executing @var{program} with the\n"
- "given @var{arguments}, a list of one or more strings, and\n"
- "return its PID. Raise a @code{system-error} exception if\n"
+ "given @var{arguments}, a list of one or more strings (by\n"
+ "convention, the first argument is typically @var{program}),\n"
+ "and return its PID. Raise a @code{system-error} exception if\n"
"@var{program} could not be found or could not be executed.\n\n"
"If the keyword argument @code{#:search-path?} is true, it\n"
"selects whether the @env{PATH} environment variable should be\n"
@@ -1441,6 +1442,12 @@ SCM_DEFINE (scm_spawn_process, "spawn", 2, 0, 1,
char *exec_file, **exec_argv, **exec_env;
int in, out, err;
+ /* In theory 'exec' accepts zero arguments, but programs are typically
+ not prepared for that and POSIX says: "The value in argv[0] should
+ point to a filename string that is associated with the process
+ image being started" (see
+
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html>).
*/
+ SCM_VALIDATE_NONEMPTYLIST (1, arguments);
env = SCM_UNDEFINED;
in_scm = SCM_UNDEFINED;
@@ -1456,14 +1463,12 @@ SCM_DEFINE (scm_spawn_process, "spawn", 2, 0, 1,
kw_search_path, &use_path,
SCM_UNDEFINED);
- exec_file = scm_to_locale_string (program);
-
scm_dynwind_begin (0);
+
+ exec_file = scm_to_locale_string (program);
scm_dynwind_free (exec_file);
exec_argv = scm_i_allocate_string_pointers (arguments);
- if (exec_argv[0] == NULL)
- SCM_MISC_ERROR ("empty argument list", SCM_EOL);
if (SCM_UNBNDP (env))
exec_env = environ;
@@ -1562,7 +1567,8 @@ piped_process (pid_t *pid, SCM prog, SCM args, SCM from,
SCM to)
break;
default: /* ENOENT, etc. */
- /* Create a dummy process that exits with value 127. */
+ /* Report the error on the console (before switching to
+ 'posix_spawn', the child process would do exactly that.) */
dprintf (err, "In execvp of %s: %s\n", exec_file,
strerror (errno_save));
}