mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-07-05 17:20:18 +02:00
* posix.texi (Pipes): Expand and clarify a bit. Describe port
inheritance. Caution against waitpid WAIT_ANY.
This commit is contained in:
parent
65f1345f16
commit
cb62d8e556
1 changed files with 70 additions and 24 deletions
|
@ -1828,7 +1828,7 @@ controlling terminal. The return value is unspecified.
|
||||||
@node Pipes
|
@node Pipes
|
||||||
@subsection Pipes
|
@subsection Pipes
|
||||||
|
|
||||||
The following procedures provide an interface to the @code{popen} and
|
The following procedures are similar to the @code{popen} and
|
||||||
@code{pclose} system routines. The code is in a separate ``popen''
|
@code{pclose} system routines. The code is in a separate ``popen''
|
||||||
module:
|
module:
|
||||||
|
|
||||||
|
@ -1837,35 +1837,64 @@ module:
|
||||||
@end smalllisp
|
@end smalllisp
|
||||||
|
|
||||||
@findex popen
|
@findex popen
|
||||||
@deffn {Scheme Procedure} open-pipe command modes
|
@deffn {Scheme Procedure} open-pipe command mode
|
||||||
Executes the shell command @var{command} (a string) in a subprocess. A
|
@deffnx {Scheme Procedure} open-pipe* mode prog [args...]
|
||||||
pipe to the process is created and returned. @var{modes} specifies
|
Execute a command in a subprocess, with a pipe to it or from it, or
|
||||||
whether an input or output pipe to the process is created: it should be
|
with pipes in both directions.
|
||||||
the value of @code{OPEN_READ}, @code{OPEN_WRITE}, or @code{OPEN_BOTH}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} open-pipe* mode command [args...]
|
@code{open-pipe} runs the shell @var{command} using @samp{/bin/sh -c}.
|
||||||
Executes the program @var{command} with optional arguments @var{args}
|
@code{open-pipe*} executes @var{prog} directly, with the optional
|
||||||
(all strings) in a subprocess. A port to the process (based on pipes)
|
@var{args} arguments (all strings).
|
||||||
is created and returned. @var{modes} specifies whether an input, an
|
|
||||||
output or an input-output port to the process is created: it should be
|
@var{mode} should be one of the following values. @code{OPEN_READ} is
|
||||||
the value of @code{OPEN_READ}, @code{OPEN_WRITE}, or @code{OPEN_BOTH}.
|
an input pipe, ie.@: to read from the subprocess. @code{OPEN_WRITE}
|
||||||
|
is an output pipe, ie.@: to write to it.
|
||||||
|
|
||||||
|
@defvar OPEN_READ
|
||||||
|
@defvarx OPEN_WRITE
|
||||||
|
@defvarx OPEN_BOTH
|
||||||
|
@end defvar
|
||||||
|
|
||||||
|
For an input pipe, the child's standard output is the pipe and
|
||||||
|
standard input is inherited from @code{current-input-port}. For an
|
||||||
|
output pipe, the child's standard input is the pipe and standard
|
||||||
|
output is inherited from @code{current-output-port}. In all cases
|
||||||
|
cases the child's standard error is inherited from
|
||||||
|
@code{current-error-port} (@pxref{Default Ports}).
|
||||||
|
|
||||||
|
If those @code{current-X-ports} are not files of some kind, and hence
|
||||||
|
don't have file descriptors for the child, then @file{/dev/null} is
|
||||||
|
used instead.
|
||||||
|
|
||||||
|
Care should be taken with @code{OPEN_BOTH}, a deadlock will occur if
|
||||||
|
both parent and child are writing, and waiting until the write
|
||||||
|
completes before doing any reading. Each direction has
|
||||||
|
@code{PIPE_BUF} bytes of buffering (@pxref{Ports and File
|
||||||
|
Descriptors}), which will be enough for small writes, but not for say
|
||||||
|
putting a big file through a filter.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} open-input-pipe command
|
@deffn {Scheme Procedure} open-input-pipe command
|
||||||
Equivalent to @code{open-pipe} with mode @code{OPEN_READ}.
|
Equivalent to @code{open-pipe} with mode @code{OPEN_READ}.
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
(read-line (open-input-pipe "date"))
|
(let* ((port (open-input-pipe "date --utc"))
|
||||||
@result{} "Mon Mar 11 20:10:44 GMT 2002"
|
(str (read-line port)))
|
||||||
|
(close-pipe port)
|
||||||
(waitpid WAIT_ANY)
|
str)
|
||||||
@result{} (24160 . 0)
|
@result{} "Mon Mar 11 20:10:44 UTC 2002"
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} open-output-pipe command
|
@deffn {Scheme Procedure} open-output-pipe command
|
||||||
Equivalent to @code{open-pipe} with mode @code{OPEN_WRITE}.
|
Equivalent to @code{open-pipe} with mode @code{OPEN_WRITE}.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(let ((port (open-output-pipe "lpr")))
|
||||||
|
(display "Something for the line printer.\n" port)
|
||||||
|
(if (not (eqv? 0 (status:exit-val (close-pipe port))))
|
||||||
|
(error "Cannot print")))
|
||||||
|
@end lisp
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} open-input-output-pipe command
|
@deffn {Scheme Procedure} open-input-output-pipe command
|
||||||
|
@ -1874,14 +1903,31 @@ Equivalent to @code{open-pipe} with mode @code{OPEN_BOTH}.
|
||||||
|
|
||||||
@findex pclose
|
@findex pclose
|
||||||
@deffn {Scheme Procedure} close-pipe port
|
@deffn {Scheme Procedure} close-pipe port
|
||||||
Closes the pipe created by @code{open-pipe}, then waits for the process
|
Close a pipe created by @code{open-pipe}, wait for the process to
|
||||||
to terminate and returns its status value, @xref{Processes, waitpid}, for
|
terminate, and return the wait status code. The status is as per
|
||||||
information on how to interpret this value.
|
@code{waitpid} and can be decoded with @code{status:exit-val} etc
|
||||||
|
(@pxref{Processes})
|
||||||
@code{close-port} (@pxref{Closing, close-port}) can also be used to
|
|
||||||
close a pipe, but doesn't return the status.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@sp 1
|
||||||
|
@code{waitpid WAIT_ANY} should not be used when pipes are open, since
|
||||||
|
it can reap a pipe's child process, causing an error from a subsequent
|
||||||
|
@code{close-pipe}.
|
||||||
|
|
||||||
|
@code{close-port} (@pxref{Closing}) can close a pipe, but it doesn't
|
||||||
|
reap the child process.
|
||||||
|
|
||||||
|
The garbage collector will close a pipe no longer in use, and reap the
|
||||||
|
child process with @code{waitpid}. If the child hasn't yet terminated
|
||||||
|
the garbage collector doesn't block, but instead checks again in the
|
||||||
|
next GC.
|
||||||
|
|
||||||
|
Many systems have per-user and system-wide limits on the number of
|
||||||
|
processes, and a system-wide limit on the number of pipes, so pipes
|
||||||
|
should be closed explicitly when no longer needed, rather than letting
|
||||||
|
the garbage collector pick them up at some later time.
|
||||||
|
|
||||||
|
|
||||||
@node Networking
|
@node Networking
|
||||||
@subsection Networking
|
@subsection Networking
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue