Previous: Querying the process environment, Up: Support For Unix

#### 7.3.3 Running external programs

External programs can be run with `sb-ext:run-program`. 1

— Function: sb-ext:run-program program args &key env environment wait search pty input if-input-does-not-exist output if-output-exists error if-error-exists status-hook

> `run-program` creates a new process specified by the `program` argument. `args` are the standard arguments that can be passed to a program. For no arguments, use `nil` (which means that just the name of the program is passed as arg 0).

> The program arguments and the environment are encoded using the default external format for streams.

> `run-program` will return a `process` structure. See the `cmu` Common Lisp Users Manual for details about the `process` structure.

> Notes about Unix environments (as in the `:environment` and `:env` args):

> - The `sbcl` implementation of `run-program`, like Perl and many other programs, but unlike the original `cmu` `cl` implementation, copies the Unix environment by default.
> - Running Unix programs from a setuid process, or in any other situation where the Unix environment is under the control of someone else, is a mother lode of security problems. If you are contemplating doing this, read about it first. (The Perl community has a lot of good documentation about this and other security issues in script-like programs.)
> The `&key` arguments have the following meanings:
> `:environment`
>   a list of STRINGs describing the new Unix environment (as in "man environ"). The default is to copy the environment of the current process.
> `:env`
>   an alternative lossy representation of the new Unix environment, for compatibility with `cmu` `cl`
> `:search`
>   Look for `program` in each of the directories in the child's $PATH environment variable. Otherwise an absolute pathname is required.
> `:wait`
>   If non-NIL (default), wait until the created process finishes. If `nil`, continue running Lisp until the program finishes.
> `:pty`
>   Either `t`, `nil`, or a stream. Unless `nil`, the subprocess is established under a `pty`. If :pty is a stream, all output to this pty is sent to this stream, otherwise the `process-pty` slot is filled in with a stream connected to pty that can read output and write input.
> `:input`
>   Either `t`, `nil`, a pathname, a stream, or `:stream`. If `t`, the standard input for the current process is inherited. If `nil`, /dev/null is used. If a pathname, the file so specified is used. If a stream, all the input is read from that stream and sent to the subprocess. If `:stream`, the `process-input` slot is filled in with a stream that sends its output to the process. Defaults to `nil`.
> `:if-input-does-not-exist` (when `:input` is the name of a file)
>   can be one of: `:error` to generate an error `:create` to create an empty file `nil` (the default) to return `nil` from `run-program`
> `:output`
>   Either `t`, `nil`, a pathname, a stream, or `:stream`. If `t`, the standard output for the current process is inherited. If `nil`, /dev/null is used. If a pathname, the file so specified is used. If a stream, all the output from the process is written to this stream. If `:stream`, the `process-output` slot is filled in with a stream that can be read to get the output. Defaults to `nil`.
> `:if-output-exists` (when `:output` is the name of a file)
>   can be one of: `:error` (the default) to generate an error `:supersede` to supersede the file with output from the program `:append` to append output from the program to the file `nil` to return `nil` from `run-program`, without doing anything
> `:error` and `:if-error-exists`
>   Same as `:output` and `:if-output-exists`, except that `:error` can also be specified as `:output` in which case all error output is routed to the same place as normal output.
> `:status-hook`
>   This is a function the system calls whenever the status of the process changes. The function takes the process as an argument.

When `sb-ext:run-program` is called with `wait` equal to NIL, an instance of class sb-ext:process is returned. The following functions are available for use with processes:

— Function: sb-ext:process-p object

> Returns true if argument is a `queue`, `nil` otherwise.

— Function: sb-ext:process-input instance

> Name of a `queue`. Can be assingned to using `setf`. Queue names can be arbitrary printable objects, and need not be unique.

— Function: sb-ext:process-output instance

> Name of a `queue`. Can be assingned to using `setf`. Queue names can be arbitrary printable objects, and need not be unique.

— Function: sb-ext:process-error instance

> Name of a `queue`. Can be assingned to using `setf`. Queue names can be arbitrary printable objects, and need not be unique.

— Function: sb-ext:process-alive-p process

> Return `t` if `process` is still alive, `nil` otherwise.

— Function: sb-ext:process-status process

> Return the current status of `process`. The result is one of `:running`, `:stopped`, `:exited`, or `:signaled`.

— Function: sb-ext:process-wait process &optional check-for-stopped

> Wait for `process` to quit running for some reason. When `check-for-stopped` is `t`, also returns when `process` is stopped. Returns `process`.

— Function: sb-ext:process-exit-code instance

> Name of a `queue`. Can be assingned to using `setf`. Queue names can be arbitrary printable objects, and need not be unique.

— Function: sb-ext:process-core-dumped instance

> Name of a `queue`. Can be assingned to using `setf`. Queue names can be arbitrary printable objects, and need not be unique.

— Function: sb-ext:process-close process

> Close all streams connected to `process` and stop maintaining the status slot.

— Function: sb-ext:process-kill process signal &optional whom

> Hand `signal` to `process`. If `whom` is `:pid`, use the kill Unix system call. If `whom` is `:process-group`, use the killpg Unix system call. If `whom` is `:pty-process-group` deliver the signal to whichever process group is currently in the foreground.

#### Footnotes

[1] In SBCL versions prior to 1.0.13, `sb-ext:run-program` searched for executables in a manner somewhat incompatible with other languages. As of this version, SBCL uses the system library routine `execvp(3)`, and no longer contains the function, `find-executable-in-search-path`, which implemented the old search. Users who need this function may find it in `run-program.lisp` versions 1.67 and earlier in SBCL's CVS repository here http://sbcl.cvs.sourceforge.net/sbcl/sbcl/src/code/run-program.lisp?view=log. However, we caution such users that this search routine finds executables that system library routines do not.