guile-commits
[Top][All Lists]
Advanced

[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));
       }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]