15.4 Processes

► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

▼ | 15 | Operating System

15.1 | Paths
15.2 | Filesystem
15.3 | Networking
15.4 | Processes
15.5 | Logging
15.6 | Time
15.7 | Environment Variables
15.8 | Environment and Runtime Information
15.9 | Command-Line Parsing
15.10 | Additional Operating System Functions

► | 15.4 | Processes

15.4.1 | Simple Subprocesses

On this page:

subprocess
subprocess-wait
subprocess-status
subprocess-kill
subprocess-pid
subprocess?
current-subprocess-custodian-mode
subprocess-group-enabled
current-subprocess-keep-file-descriptors
shell-execute
15.4.1`` Simple Subprocesses
system
system*
system/ exit-code
system*/ exit-code
process
process*
process/ ports
process*/ ports
string-no-nuls?
bytes-no-nuls?

top contents ← prev up next →

#### 15.4`` Processes🔗ℹ

> > procedure
> > (subprocess |  | stdout |
> > |  | stdin |
> > |  | stderr |
> > | [ | group] |
> > |  | command |
> > |  | arg ...) |
> | → |  |
> subprocess?
> (or/c (and/c input-port? file-stream-port?) #f)
> (or/c (and/c output-port? file-stream-port?) #f)
> (or/c (and/c input-port? file-stream-port?) #f)
> stdout : (or/c (and/c output-port? file-stream-port?) #f)
> stdin : (or/c (and/c input-port? file-stream-port?) #f)
> stderr : (or/c (and/c output-port? file-stream-port?) #f 'stdout)
> | group |  | : |  | (or/c #f 'new subprocess)
> |  |  | = |  | (and (subprocess-group-enabled) 'new)
> command : path-string?
> arg : (or/c path? string-no-nuls? bytes-no-nuls?)
> (subprocess |  | stdout |
> |  | stdin |
> |  | stderr |
> | [ | group] |
> |  | command |
> |  | exact |
> |  | arg) |
> | → |  |
> subprocess?
> (or/c (and/c input-port? file-stream-port?) #f)
> (or/c (and/c output-port? file-stream-port?) #f)
> (or/c (and/c input-port? file-stream-port?) #f)
> stdout : (or/c (and/c output-port? file-stream-port?) #f)
> stdin : (or/c (and/c input-port? file-stream-port?) #f)
> stderr : (or/c (and/c output-port? file-stream-port?) #f)
> | group |  | : |  | (or/c #f 'new subprocess)
> |  |  | = |  | (and (subprocess-group-enabled) 'new)
> command : path-string?
> exact : 'exact
> arg : string?

Creates a new process in the underlying operating system to execute command asynchronously, providing the new process with environment variables current-environment-variables. See also system and process from racket/system.

> > > On Unix and Mac OS, subprocess creation is separate from starting the program indicated by command. In particular, if command refers to a non-existent or non-executable file, an error will be reported (via standard error and a non-0 exit code) in the subprocess, not in the creating process.

The command argument is a path to a program executable, and the args are command-line arguments for the program. See find-executable-path for locating an executable based on the PATH environment variable. On Unix and Mac OS, command-line arguments are passed as byte strings, and string args are converted using the current locale’s encoding (see Encodings and Locales). On Windows, command-line arguments are passed as strings, and byte strings are converted using UTF-8.

On Windows, a process natively receives a single command-line argument string, unlike Unix and Mac OS processes that natively receive an array of arguments. A Windows command-line string is constructed from command and args following a Windows convention so that a typical application can parse it back to an array of arguments, For information on the Windows command-line conventions, see Microsoft’s documentation source or search for “command line parsing” at http://msdn.microsoft.com/. but beware that an application may parse the command line in a different way. In particular, take special care when supplying a command that refers to a ".bat" or ".cmd" file, because the command-line string delivered to the process will be parsed as a cmd.exe command, which is effectively a different syntax than the convention that subprocess uses to encode command-line arguments; supplying unsanitized args could enable parsing of arguments as commands. To enable more control over the command-line string that is delivered to a process, the first arg can be replaced with 'exact, which triggers a Windows-specific behavior: the sole arg is used exactly as the command-line for the subprocess. If 'exact is provided on a non-Windows platform, the exn:fail:contract exception is raised.

When provided as a port, stdout is used for the launched process’s standard output, stdin is used for the process’s standard input, and stderr is used for the process’s standard error. All provided ports must be file-stream ports. Any of the ports can be #f, in which case a system pipe is created and returned by subprocess. The stderr argument can be 'stdout, in which case the same file-stream port or system pipe that is supplied as standard output is also used for standard error. For each port or 'stdout that is provided, no pipe is created and the corresponding returned value is #f. If stdout or stderr is a port for which port-waiting-peer? returns true, then subprocess waits for the port to become ready for writing before proceeding with the subprocess creation.

If group is 'new, then the new process is created as a new OS-level process group. In that case, subprocess-kill attempts to terminate all processes within the group, which may include additional processes created by the subprocess. Beware that creating a group may interfere with the job control in an interactive shell, since job control is based on process groups. See subprocess-kill for details. If group is a subprocess, then that subprocess must have been created with 'new, and the new subprocess will be added to the group; adding to the group will succeed only on Unix and Mac OS, and only in the same cases that subprocess-kill would have an effect (i.e., the subprocess is not known to have terminated), otherwise it will fail silently.

The subprocess procedure returns four values:

- a subprocess value representing the created process;

- an input port piped from the process’s standard output, or #f if stdout was a port;

- an output port piped to the process’s standard input, or #f if stdin was a port;

- an input port piped from the process’s standard error, or #f if stderr was a port or 'stdout.

Important: All ports returned from subprocess must be explicitly closed, usually with close-input-port or close-output-port.

> > > A file-stream port for communicating with a subprocess is normally a pipe with a limited capacity. Beware of creating deadlock by serializing a write to a subprocess followed by a read, while the subprocess does the same, so that both processes end up blocking on a write because the other end must first read to make room in the pipe. Beware also of waiting for a subprocess to finish without reading its output, because the subprocess may be blocked attempting to write output into a full pipe.

The returned ports are file-stream ports (see File Ports), and they are placed into the management of the current custodian (see Custodians). The exn:fail exception is raised when a low-level error prevents the spawning of a process or the creation of operating system pipes for process communication.

The current-subprocess-custodian-mode parameter determines whether the subprocess itself is registered with the current custodian so that a custodian shutdown calls subprocess-kill for the subprocess.

The current-subprocess-keep-file-descriptors parameter determines how file descriptors and handles in the current process are shared with the subprocess. File descriptors (on Unix and Mac OS) or handles (on Windows) represented by stdin, stdout, and stderr are always shared with the subprocess. File descriptors and handles that are replaced by newly created pipes (when the corresponding stdin, stdout, and stderr argument is #f) are not shared. Sharing for other file descriptors and handles depends on the parameter value:

- 'inherited (the default) — other handles that are inherited on Windows are shared with the subprocess; file descriptors that lack the FD_CLOEXEC flag on Unix and Mac OS variants that support the flag are also shared; and no other file descriptors are shared on variants of Unix and Mac OS that do not support FD_CLOEXEC.

- 'all — like 'inherited, except on variants of Unix and Mac OS that do not support FD_CLOEXEC, in which case all file descriptors are shared.

- '() — no additional file descriptors are shared, not even ones that are inherited on Windows or lacking the FD_CLOEXEC flag.

A subprocess can be used as a synchronizable event (see Events). A subprocess value is ready for synchronization when subprocess-wait would not block; the synchronization result of a subprocess value is the subprocess value itself.

Example:

> (define-values (sp out in err)
> (subprocess #f #f #f "/bin/ls" "-l"))
> (printf "stdout:\n~a" (port->string out))
> (printf "stderr:\n~a" (port->string err))
> (close-input-port out)
> (close-output-port in)
> (close-input-port err)
> (subprocess-wait sp)

Changed in version 6.11.0.1 of package base: Added the group argument.
Changed in version 7.4.0.5: Added waiting for a fifo without a reader as stdout and/or stderr.
Changed in version 8.3.0.4: Added current-subprocess-custodian-mode support.
Changed in version 8.11.1.6: Changed the treatment of file-descriptor sharing on variants of Unix and Mac OS that support FD_CLOEXEC.

> procedure (subprocess-wait subproc) → void?
> subproc : subprocess?

Blocks until the process represented by subproc terminates. The subproc value also can be used with sync and sync/timeout.

> > procedure
> > (subprocess-status subproc) |  | → |  |
> > (or/c 'running
> > exact-nonnegative-integer?)
> subproc : subprocess?

Returns 'running if the process represented by subproc is still running, or its exit code otherwise. The exit code is an exact integer, and 0 typically indicates success. If the process terminated due to a fault or signal, the exit code is non-zero.

> procedure (subprocess-kill subproc force?) → void?
> subproc : subprocess?
> force? : any/c

Terminates the subprocess represented by subproc. The precise action depends on whether force? is true, whether the process was created in its own group by setting the subprocess-group-enabled parameter to a true value, and the current platform:

- force? is true, not a group, all platforms: Terminates the process if the process still running.

- force? is false, not a group, on Unix or Mac OS: Sends the process an interrupt signal instead of a kill signal.

- force? is false, not a group, on Windows: No action is taken.

- force? is true, a group, on Unix or Mac OS: Terminates all processes in the group, but only if subprocess-status has never produced a non-'running result for the subprocess and only if functions like subprocess-wait and sync have not detected the subprocess’s completion. Otherwise, no action is taken (because the immediate process is known to have terminated while the continued existence of the group is unknown).

- force? is true, a group, on Windows: Terminates the process if the process still running.

- force? is false, a group, on Unix or Mac OS: The same as when force? is #t, but when the group is sent a signal, it is an interrupt signal instead of a kill signal.

- force? is false, a group, on Windows: All processes in the group receive a CTRL-BREAK signal (independent of whether the immediate subprocess has terminated).

If an error occurs during termination, the exn:fail exception is raised.

> procedure (subprocess-pid subproc) → exact-nonnegative-integer?
> subproc : subprocess?

Returns the operating system’s numerical ID (if any) for the process represented by subproc. The result is valid only as long as the process is running.

> procedure (subprocess? v) → boolean?
> v : any/c

Returns #t if v is a subprocess value, #f otherwise.

> parameter (current-subprocess-custodian-mode)
> → (or/c #f 'kill 'interrupt)
> (current-subprocess-custodian-mode mode) → void?
> mode : (or/c #f 'kill 'interrupt)

A parameter that determines whether a subprocess (as created by subprocess or wrappers like process) is registered with the current custodian. If the parameter value is #f, then the subprocess is not registered with the custodian—although any created ports are registered. If the parameter value is 'kill or 'interrupt, then the subprocess is shut down through subprocess-kill, where 'kill supplies a #t value for the force? argument and 'interrupt supplies a #f value. The shutdown may occur either before or after ports created for the subprocess are closed.

Custodian-triggered shutdown is limited by details of process handling in the host system. For example, process and system may create an intermediate shell process to run a program, in which case custodian-based termination shuts down the shell process and probably not the process started by the shell. See also subprocess-kill. Process groups (see subprocess-group-enabled) can address some limitations, but not all of them.

> parameter (subprocess-group-enabled) → boolean?
> (subprocess-group-enabled on?) → void?
> on? : any/c

A parameter that determines whether a subprocess is created as a new process group by default. See subprocess and subprocess-kill for more information.

> parameter (current-subprocess-keep-file-descriptors)
> → (or/c 'inherited 'all '())
> (current-subprocess-keep-file-descriptors keeps) → void?
> keeps : (or/c 'inherited 'all '())

A parameter that determines how file descriptors (on Unix and Mac OS) and handles (on Windows) are shared in a subprocess as created by subprocess or wrappers like process. See subprocess for more information.

Added in version 8.3.0.4 of package base.

> > procedure
> > (shell-execute |  | verb |  |  |  |
> > |  | target |  |  |  |
> > |  | parameters |  |  |  |
> > |  | dir |  |  |  |
> > |  | show-mode) |  | → |  | #f
> verb : (or/c string? #f)
> target : string?
> parameters : string?
> dir : path-string?
> show-mode : symbol?

Performs the action specified by verb on target in Windows. For platforms other than Windows, the exn:fail:unsupported exception is raised.

For example,

> (shell-execute #f "http://racket-lang.org" ""
> (current-directory) 'sw_shownormal)

Opens the Racket home page in a browser window.

The verb can be #f, in which case the operating system will use a default verb. Common verbs include "open", "edit", "find", "explore", and "print".

The target is the target for the action, usually a filename path. The file could be executable, or it could be a file with a recognized extension that can be handled by an installed application.

The parameters argument is passed on to the system to perform the action. For example, in the case of opening an executable, the parameters is used as the command line (after the executable name).

The dir is used as the current directory when performing the action.

The show-mode sets the display mode for a Window affected by the action. It must be one of the following symbols; the description of each symbol’s meaning is taken from the Windows API documentation.

- 'sw_hide or 'SW_HIDE — Hides the window and activates another window.

- 'sw_maximize or 'SW_MAXIMIZE — Maximizes the window.

- 'sw_minimize or 'SW_MINIMIZE — Minimizes the window and activates the next top-level window in the z-order.

- 'sw_restore or 'SW_RESTORE — Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position.

- 'sw_show or 'SW_SHOW — Activates the window and displays it in its current size and position.

- 'sw_showdefault or 'SW_SHOWDEFAULT — Uses a default.

- 'sw_showmaximized or 'SW_SHOWMAXIMIZED — Activates the window and displays it as a maximized window.

- 'sw_showminimized or 'SW_SHOWMINIMIZED — Activates the window and displays it as a minimized window.

- 'sw_showminnoactive or 'SW_SHOWMINNOACTIVE — Displays the window as a minimized window. The active window remains active.

- 'sw_showna or 'SW_SHOWNA — Displays the window in its current state. The active window remains active.

- 'sw_shownoactivate or 'SW_SHOWNOACTIVATE — Displays a window in its most recent size and position. The active window remains active.

- 'sw_shownormal or 'SW_SHOWNORMAL — Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position.

If the action fails, the exn:fail exception is raised. If the action succeeds, the result is #f.

In future versions of Racket, the result may be a subprocess value if the operating system did returns a process handle (but if a subprocess value is returned, its process ID will be 0 instead of the real process ID).

##### 15.4.1`` Simple Subprocesses🔗ℹ

(require racket/system) | package: base

The bindings documented in this section are provided by the racket/system and racket libraries, but not racket/base.

> procedure (system command [#:set-pwd? set-pwd?]) → boolean?
> command : (or/c string-no-nuls? bytes-no-nuls?)
> set-pwd? : any/c = (member (system-type) '(unix macosx))

Executes a shell command synchronously (i.e., the call to system does not return until the subprocess has ended). On Unix and Mac OS, /bin/sh is used as the shell, while cmd.exe or command.com (if cmd.exe is not found) is used on Windows. The command argument is a string or byte string containing no nul characters. If the command succeeds, the return value is #t, #f otherwise.

> > > See also subprocess for notes about error handling and the limited buffer capacity of subprocess pipes.

If set-pwd? is true, then the PWD environment variable is set to the value of (current-directory) when starting the shell process.

See also current-subprocess-custodian-mode and subprocess-group-enabled, which affect the subprocess used to implement system.

The resulting process writes to (current-output-port), reads from (current-input-port), and logs errors to (current-error-port). To gather the process’s non-error output to a string, for example, use with-output-to-string, which sets current-output-port while calling the given function:

> (with-output-to-string (lambda () (system "date")))

> procedure (system* command arg ... [#:set-pwd? set-pwd?]) → boolean?
> command : path-string?
> arg : (or/c path? string-no-nuls? bytes-no-nuls?)
> set-pwd? : any/c = (member (system-type) '(unix macosx))
> (system* |  | command |  |  |  |
> |  | exact |  |  |  |
> |  | arg |  |  |  |
> | [ | #:set-pwd? set-pwd?]) |  | → |  | boolean?
> command : path-string?
> exact : 'exact
> arg : string?
> set-pwd? : any/c = (member (system-type) '(unix macosx))

Like system, except that command is a filename that is executed directly (instead of through a shell command; see find-executable-path for locating an executable based on the PATH environment variable), and the args are the arguments. The executed file is passed the specified string arguments (which must contain no nul characters).

On Windows, the first argument after command can be 'exact, and the final arg is a complete command line. See subprocess for details and for a specific warning about using a command that refers to a ".bat" or ".cmd" file.

> > procedure
> > (system/exit-code |  | command |  |  |  |
> > | [ | #:set-pwd? set-pwd?]) |  | → |  | byte?
> command : (or/c string-no-nuls? bytes-no-nuls?)
> set-pwd? : any/c = (member (system-type) '(unix macosx))

Like system, except that the result is the exit code returned by the subprocess. A 0 result normally indicates success.

> > procedure
> > (system*/exit-code |  | command |  |  |  |
> > |  | arg ... |  |  |  |
> > | [ | #:set-pwd? set-pwd?]) |  | → |  | byte?
> command : path-string?
> arg : (or/c path? string-no-nuls? bytes-no-nuls?)
> set-pwd? : any/c = (member (system-type) '(unix macosx))
> (system*/exit-code |  | command |  |  |  |
> |  | exact |  |  |  |
> |  | arg |  |  |  |
> | [ | #:set-pwd? set-pwd?]) |  | → |  | byte?
> command : path-string?
> exact : 'exact
> arg : string?
> set-pwd? : any/c = (member (system-type) '(unix macosx))

Like system*, but returns the exit code like system/exit-code.

> procedure (process command [#:set-pwd? set-pwd?])
> | → |  |
> (list input-port?
> output-port?
> exact-nonnegative-integer?
> input-port?
> ((or/c 'status 'wait 'interrupt 'kill) . -> . any))
> command : (or/c string-no-nuls? bytes-no-nuls?)
> set-pwd? : any/c = (member (system-type) '(unix macosx))

Executes a shell command asynchronously (using /bin/sh on Unix and Mac OS, cmd.exe or command.com on Windows). The result is a list of five values:

> > > See also subprocess for notes about error handling and the limited buffer capacity of subprocess pipes.

- an input port piped from the subprocess’s standard output,

- an output port piped to the subprocess’s standard input,

- the system process id of the subprocess,

- an input port piped from the subprocess’s standard error, and

- a procedure of one argument, either 'status, 'wait, 'interrupt, 'exit-code or 'kill:

  - 'status returns the status of the subprocess as one of 'running, 'done-ok, or 'done-error.

  - 'exit-code returns the integer exit code of the subprocess or #f if it is still running.

  - 'wait blocks execution in the current thread until the subprocess has completed.

  - 'interrupt sends the subprocess an interrupt signal on Unix and Mac OS, and takes no action on Windows. The result is #<void>.

    > > > On Unix and Mac OS, if command runs a single program, then /bin/sh typically runs the program in such a way that it replaces /bin/sh in the same process. For reliable and precise control over process creation, however, use process*.

  - 'kill terminates the subprocess and returns #<void>. Note that the immediate process created by process is a shell process that may run another program; terminating the shell process may not terminate processes that the shell starts, particularly on Windows.

Important: All three ports returned from process must be explicitly closed with close-input-port or close-output-port.

If set-pwd? is true, then PWD is set in the same way as system.

See also current-subprocess-custodian-mode and subprocess-group-enabled, which affect the subprocess used to implement process. In particular, the 'interrupt and 'kill process-control messages are implemented via subprocess-kill, so they can affect a process group instead of a single process.

> > procedure
> > (process* |  | command |  |  |  |
> > |  | arg ... |  |  |  |
> > | [ | #:set-pwd? set-pwd?]) |  | → |  | list?
> command : path-string?
> arg : (or/c path? string-no-nuls? bytes-no-nuls?)
> set-pwd? : any/c = (member (system-type) '(unix macosx))
> (process* |  | command |  |  |  |
> |  | exact |  |  |  |
> |  | arg |  |  |  |
> | [ | #:set-pwd? set-pwd?]) |  | → |  | list?
> command : path-string?
> exact : 'exact
> arg : string?
> set-pwd? : any/c = (member (system-type) '(unix macosx))

Like process, except that command is a filename that is executed directly like system*, and the args are the arguments.

On Windows, as for system*, the first arg can be replaced with 'exact. See also subprocess for a specific warning about using a command that refers to a ".bat" or ".cmd" file.

> > procedure
> > (process/ports |  | out |  |  |  |
> > |  | in |  |  |  |
> > |  | error-out |  |  |  |
> > |  | command |  |  |  |
> > | [ | #:set-pwd? set-pwd?]) |  | → |  | list?
> out : (or/c #f output-port?)
> in : (or/c #f input-port?)
> error-out : (or/c #f output-port? 'stdout)
> command : (or/c path? string-no-nuls? bytes-no-nuls?)
> set-pwd? : any/c = (member (system-type) '(unix macosx))

Like process, except that out is used for the process’s standard output, in is used for the process’s standard input, and error-out is used for the process’s standard error. Any of the ports can be #f, in which case a system pipe is created and returned, as in process. If error-out is 'stdout, then standard error is redirected to standard output. For each port or 'stdout that is provided, no pipe is created, and the corresponding value in the returned list is #f.

> > procedure
> > (process*/ports |  | out |  |  |  |
> > |  | in |  |  |  |
> > |  | error-out |  |  |  |
> > |  | command |  |  |  |
> > |  | arg ... |  |  |  |
> > | [ | #:set-pwd? set-pwd?]) |  | → |  | list?
> out : (or/c #f output-port?)
> in : (or/c #f input-port?)
> error-out : (or/c #f output-port? 'stdout)
> command : path-string?
> arg : (or/c path? string-no-nuls? bytes-no-nuls?)
> set-pwd? : any/c = (member (system-type) '(unix macosx))
> (process*/ports |  | out |  |  |  |
> |  | in |  |  |  |
> |  | error-out |  |  |  |
> |  | command |  |  |  |
> |  | exact |  |  |  |
> |  | arg |  |  |  |
> | [ | #:set-pwd? set-pwd?]) |  | → |  | list?
> out : (or/c #f output-port?)
> in : (or/c #f input-port?)
> error-out : (or/c #f output-port? 'stdout)
> command : path-string?
> exact : 'exact
> arg : string?
> set-pwd? : any/c = (member (system-type) '(unix macosx))

Like process*, but with the port handling of process/ports.

The contracts of system and related functions may signal a contract error with references to the following functions.

> procedure (string-no-nuls? x) → boolean?
> x : any/c

Ensures that x is a string and does not contain "\u0000".

> procedure (bytes-no-nuls? x) → boolean?
> x : any/c

Ensures that x is a byte-string and does not contain #"\0".
top contents ← prev up next →