Next: , Previous: , Up: POSIX   [Contents][Index]


7.2.10 Pipes

The following procedures are similar to the popen and pclose system routines. The code is in a separate “popen” module24:

(use-modules (ice-9 popen))
Scheme Procedure: open-pipe command mode
Scheme Procedure: open-pipe* mode prog [args...]

Execute a command in a subprocess, with a pipe to it or from it, or with pipes in both directions.

open-pipe runs the shell command using ‘/bin/sh -c’. open-pipe* executes prog directly, with the optional args arguments (all strings).

mode should be one of the following values. OPEN_READ is an input pipe, ie. to read from the subprocess. OPEN_WRITE is an output pipe, ie. to write to it.

Variable: OPEN_READ
Variable: OPEN_WRITE
Variable: OPEN_BOTH

For an input pipe, the child’s standard output is the pipe and standard input is inherited from current-input-port. For an output pipe, the child’s standard input is the pipe and standard output is inherited from current-output-port. In all cases the child’s standard error is inherited from current-error-port (see Default Ports).

If those current-X-ports are not files of some kind, and hence don’t have file descriptors for the child, then /dev/null is used instead.

Care should be taken with 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 PIPE_BUF bytes of buffering (see Buffering), which will be enough for small writes, but not for say putting a big file through a filter.

Scheme Procedure: open-input-pipe command

Equivalent to open-pipe with mode OPEN_READ.

(let* ((port (open-input-pipe "date --utc"))
       (str  (read-line port))) ; from (ice-9 rdelim)
  (close-pipe port)
  str)
⇒ "Mon Mar 11 20:10:44 UTC 2002"
Scheme Procedure: open-output-pipe command

Equivalent to open-pipe with mode OPEN_WRITE.

(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")))
Scheme Procedure: open-input-output-pipe command

Equivalent to open-pipe with mode OPEN_BOTH.

Scheme Procedure: close-pipe port

Close a pipe created by open-pipe, wait for the process to terminate, and return the wait status code. The status is as per waitpid and can be decoded with status:exit-val etc (see Processes)


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 close-pipe.

close-port (see Ports) 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 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.

Scheme Procedure: pipeline commands

Execute a pipeline of commands, where each command is a list of a program and its arguments as strings, returning an input port to the end of the pipeline, an output port to the beginning of the pipeline and a list of PIDs of the processes executing the commands.

(let ((commands '(("git" "ls-files")
                  ("tar" "-cf-" "-T-")
                  ("sha1sum" "-")))
      (success? (lambda (pid)
                  (zero?
                   (status:exit-val (cdr (waitpid pid)))))))
  (receive (from to pids) (pipeline commands)
    (let* ((sha1 (read-delimited " " from))
           (index (list-index (negate success?) (reverse pids))))
      (close to)
      (close from)
      (if (not index)
          sha1
          (string-append "pipeline failed in command: "
                         (string-join (list-ref commands index)))))))
⇒ "52f99d234503fca8c84ef94b1005a3a28d8b3bc1"

Footnotes

(24)

This module is only available on systems where the popen feature is provided (see Common Feature Symbols).


Next: , Previous: , Up: POSIX   [Contents][Index]