diff options
author | Josselin Poiret <dev@jpoiret.xyz> | 2023-01-07 17:07:46 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2023-01-13 16:05:30 +0100 |
commit | 551929e4fb77341fa5309c138b2ab92966987966 (patch) | |
tree | f64410a438cba928d9c2902c55641eea73d969d0 /doc | |
parent | edfca3b7e5931b5b5a83112e2a9813b068be99c2 (diff) | |
download | guile-551929e4fb77341fa5309c138b2ab92966987966.tar.gz |
Add 'spawn'.
* libguile/posix.c: Include spawn.h from Gnulib.
(do_spawn, scm_spawn_process): New functions.
(kw_environment, hw_input, kw_output, kw_error, kw_search_path): New
variables.
* doc/ref/posix.texi (Processes): Document it.
* test-suite/tests/posix.test ("spawn"): New test prefix.
* NEWS: Update.
Co-authored-by: Ludovic Courtès <ludo@gnu.org>
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/ref/posix.texi | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi index bde0f150c..5653d3758 100644 --- a/doc/ref/posix.texi +++ b/doc/ref/posix.texi @@ -2045,15 +2045,67 @@ 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. +@quotation Note +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 with the scsh fork. @end deffn +@deffn {Scheme Procedure} spawn @var{program} @var{arguments} @ + [#:environment=(environ)] @ + [#:input=(current-input-port)] @ + [#:output=(current-output-port)] @ + [#: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 (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 +selects whether the @env{PATH} environment variable should be +inspected to find @var{program}. It is true by default. + +The @code{#:environment} keyword parameter specifies the +list of environment variables of the child process. It +defaults to @code{(environ)}. + +The keyword arguments @code{#:input}, @code{#:output}, and +@code{#:error} specify the port or file descriptor for the +child process to use as standard input, standard output, and +standard error. No other file descriptors are inherited +from the parent process. +@end deffn + +The example below shows how to spawn the @command{uname} program with +the @option{-o} option (@pxref{uname invocation,,, coreutils, GNU +Coreutils}), redirect its standard output to a pipe, and read from it: + +@lisp +(use-modules (rnrs io ports)) + +(let* ((input+output (pipe)) + (pid (spawn "uname" '("uname" "-o") + #:output (cdr input+output)))) + (close-port (cdr input+output)) + (format #t "read ~s~%" (get-string-all (car input+output))) + (close-port (car input+output)) + (waitpid pid)) + +@print{} read "GNU/Linux\n" +@result{} (1234 . 0) +@end lisp + @deffn {Scheme Procedure} nice incr @deffnx {C Function} scm_nice (incr) @cindex process priority |