chickadee » chicken » process

Module (chicken process)

This module offers procedures for interacting with subprocesses.

Processes

process-execute

process-execute PATHNAME #!optional ARGUMENT-LIST ENVIRONMENT-ALISTprocedure

Replaces the running process with a new process image from the program stored at PATHNAME, using the C library function execvp(3). If the optional argument ARGUMENT-LIST is given, then it should contain a list of strings which are passed as arguments to the subprocess. If the optional argument ENVIRONMENT-ALIST is supplied, then the library function execve(2) is used, and the environment passed in ENVIRONMENT-ALIST (which should be of the form (("<NAME>" . "<VALUE>") ...)) is given to the invoked process. Note that execvp(3) respects the current setting of the PATH environment variable while execve(3) does not.

This procedure never returns; it either replaces the process with a new one or it raises an exception in case something went wrong executing the program.

On Windows, these procedures all have an additional optional parameter EXACT-FLAG, which defaults to #f. When #f is passed, any argument string with embedded whitespace will be wrapped in quotes. When #t no such wrapping occurs.

process-fork

process-fork #!optional THUNK KILLOTHERS?procedure

Creates a new child process with the UNIX system call fork(). Returns either the PID of the child process or 0. If THUNK is given, then the child process calls it as a procedure with no arguments and terminates. If THUNK is given and the optional argument KILLOTHERS? is true, then kill all other existing threads in the child process, leaving only the current thread to run THUNK and terminate.

NOTE: On native Windows builds (all except cygwin), this procedure is unimplemented and will raise an error.

process-run

process-run COMMANDLINEprocedure
process-run COMMAND ARGUMENT-LISTprocedure

Creates a new child process. The PID of the new process is returned.

  • The single parameter version passes the COMMANDLINE to the system shell, so usual argument expansion can take place. Be careful to properly quote arguments with the qs procedure to avoid shell injection vulnerabilities.
  • The multiple parameter version directly invokes the COMMAND with the ARGUMENT-LIST, and is vastly preferred over the single-parameter version because of its better safety.

process-signal

process-signal PID #!optional SIGNALprocedure

Sends SIGNAL to the process with the id PID using the UNIX system call kill(). SIGNAL defaults to the value of the variable signal/term.

NOTE: On native Windows builds (all except cygwin), this procedure is unimplemented and will raise an error.

process-spawn

process-spawn MODE COMMAND #!optional ARGUMENT-LIST ENVIRONMENT-LIST EXACT-FLAGprocedure

Creates and runs a new process with the given COMMAND filename and the optional ARGUMENT-LIST and ENVIRONMENT-LIST. MODE specifies how exactly the process should be executed and must be one or more of the spawn/... flags listed below.

The EXACT-FLAG, default #f, controls quote-wrapping of argument strings. When #t quote-wrapping is not performed.

Returns:

  • the exit status when synchronous
  • the PID when asynchronous
  • -1 when failure

NOTE: On all Unix-like builds (all except native MingW-based Windows platforms), this procedure is unimplemented and will raise an error.

spawn/overlayconstant
spawn/waitconstant
spawn/nowaitconstant
spawn/nowaitoconstant
spawn/detachconstant

These variables contains special flags that specify the exact semantics of process-spawn:

  • spawn/overlay replaces the current process with the new one.
  • spawn/wait suspends execution of the current process until the spawned process returns.
  • spawn/nowait does the opposite (spawn/nowaito is identical, according to the Microsoft documentation) and runs the process asynchronously.
  • spawn/detach runs the new process in the background, without being attached to a console.

process-wait

process-wait #!optional PID NOHANGprocedure

Suspends the current process until the child process with the id PID has terminated using the UNIX system call waitpid(). If PID is not given, then this procedure waits for any child process. If NOHANG is given and not #f then the current process is not suspended. This procedure returns three values:

  • PID or 0, if NOHANG is true and the child process has not terminated yet.
  • #t if the process exited normally or #f otherwise.
  • either the exit status, if the process terminated normally or the signal number that terminated/stopped the process.

Note that suspending the current process implies that all threads are suspended as well.

On Windows, process-wait always returns #t for a terminated process and only the exit status is available. (Windows does not provide signals as an interprocess communication method.)

process-sleep

process-sleep SECONDSprocedure

Puts the process to sleep for SECONDS. Returns either 0 if the time has completely elapsed, or the number of remaining seconds, if a signal occurred.

process

process COMMANDLINEprocedure
process COMMAND ARGUMENT-LIST #!optional ENVIRONMENT-ALISTprocedure

Creates a subprocess and returns three values: an input port from which data written by the sub-process can be read, an output port from which any data written to will be received as input in the sub-process and the process-id of the started sub-process. Blocking reads and writes to or from the ports returned by process only block the current thread, not other threads executing concurrently.

Standard error for the subprocess is linked up to the current process's standard error (see process* if you want to reify its standard error into a separate port).

  • The single parameter version passes the string COMMANDLINE to the host-system's shell that is invoked as a subprocess.
  • The multiple parameter version directly invokes the COMMAND as a subprocess. The ARGUMENT-LIST is directly passed, as is ENVIRONMENT-ALIST. These arguments have the same form as the ones of process-execute.

Not using the shell may be preferrable for security reasons.

Once both the input- and output ports are closed, an implicit waitpid(3) is done to wait for the subprocess to finish or to reap a subprocess that has terminated. If the subprocess has not finished, waiting for it will necessarily block all executing threads.

process*

process* COMMANDLINEprocedure
process* COMMAND ARGUMENT-LIST #!optional ENVIRONMENT-ALISTprocedure

Like process but returns 4 values: an input port from which data written by the sub-process can be read, an output port from which any data written to will be received as input in the sub-process, the process-id of the started sub-process, and an input port from which data written by the sub-process to stderr can be read.

Shell commands

The commands below are all string-based. This means you have to be very careful to properly quote any arguments to subprocesses, to avoid shell injection bugs which can lead to arbitrary code execution.

You can quote arguments with the qs procedure, but it is strongly recommended you use fork with process-execute or the multi-argument versions of the process, process* or process-run procedures.

qs

qs STRING #!optional PLATFORMprocedure

Escapes STRING suitably for passing to a shell command on PLATFORM. PLATFORM defaults to the value of (build-platform) and indicates in which style the argument should be quoted. On Windows systems, the string is simply enclosed in double-quote (") characters, on UNIXish systems, characters that would have a special meaning to the shell are escaped using backslash (\).

system

system STRINGprocedure

Execute shell command. The functionality offered by this procedure depends on the capabilities of the host shell. If the forking of a subprocess failed, an exception is raised. Otherwise the return status of the subprocess is returned unaltered.

On a UNIX system, that value is the raw return value of waitpid(2), which contains signal, core dump and exit status. It is 0 on success. To pull out the signal number or exit status portably requires POSIX calls, but in a pinch you can use something like this:

;; Returns two values: #t if the process exited normally or #f otherwise;
;; and either the exit status, or the signal number if terminated via signal.
(define (process-status rc)
  (define (wait-signaled? x) (not (= 0 (bitwise-and x 127))))
  (define (wait-signal x) (bitwise-and x 127))
  (define (wait-exit-status x) (arithmetic-shift x -8))
  (if (wait-signaled? rc)
      (values #f (wait-signal rc))
      (values #t (wait-exit-status rc))))

#;> (process-status (system "exit 42"))
#t
42

system*

system* STRINGprocedure

Similar to (system STRING), but signals an error should the invoked program return a nonzero exit status.

Pipes

call-with-input-pipe

call-with-output-pipe

call-with-input-pipe CMDLINE PROC #!optional MODEprocedure
call-with-output-pipe CMDLINE PROC #!optional MODEprocedure

Call PROC with a single argument: a input- or output port for a pipe connected to the subprocess named in CMDLINE. If PROC returns normally, the pipe is closed and any result values are returned.

close-input-pipe

close-output-pipe

close-input-pipe PORTprocedure
close-output-pipe PORTprocedure

Closes the pipe given in PORT and waits until the connected subprocess finishes. The exit-status code of the invoked process is returned.

create-pipe

create-pipeprocedure

The fundamental pipe-creation operator. Calls the C function pipe() and returns 2 values: the file-descriptors of the input- and output-ends of the pipe.

On Windows, there is an optional parameter MODE, which defaults to open/binary | open/noinherit. This can be open/binary or open/text, optionally or'ed with open/noinherit.

open-input-pipe

open-input-pipe CMDLINE #!optional MODEprocedure

Spawns a subprocess with the command-line string CMDLINE and returns a port, from which the output of the process can be read. If MODE is specified, it should be the keyword #:text (the default) or #:binary.

open-output-pipe

open-output-pipe CMDLINE #!optional MODEprocedure

Spawns a subprocess with the command-line string CMDLINE and returns a port. Anything written to that port is treated as the input for the process. If MODE is specified, it should be the keyword #:text (the default) or #:binary.

pipe/buf

pipe/bufconstant

This variable contains the maximal number of bytes that can be written atomically into a pipe or FIFO.

with-input-from-pipe

with-output-to-pipe

with-input-from-pipe CMDLINE THUNK #!optional MODEprocedure
with-output-to-pipe CMDLINE THUNK #!optional MODEprocedure

Temporarily set the value of current-input-port/current-output-port to a port for a pipe connected to the subprocess named in CMDLINE and call the procedure THUNK with no arguments. After THUNK returns normally the pipe is closed and the standard input-/output port is restored to its previous value and any result values are returned.

(with-output-to-pipe
  "gs -dNOPAUSE -sDEVICE=jpeg -dBATCH -sOutputFile=signballs.jpg -g600x600 -q -"
  (lambda ()
    (print #<<EOF
 %!IOPSC-1993 %%Creator: HAYAKAWA Takashi<xxxxxxxx@xx.xxxxxx.xx.xx>
 /C/neg/d/mul/R/rlineto/E/exp/H{{cvx def}repeat}def/T/dup/g/gt/r/roll/J/ifelse 8
 H/A/copy(z&v4QX&93r9AxYQOZomQalxS2w!!O&vMYa43d6r93rMYvx2dca!D&cjSnjSnjjS3o!v&6A
 X&55SAxM1CD7AjYxTTd62rmxCnTdSST0g&12wECST!&!J0g&D1!&xM0!J0g!l&544dC2Ac96ra!m&3A
 F&&vGoGSnCT0g&wDmlvGoS8wpn6wpS2wTCpS1Sd7ov7Uk7o4Qkdw!&Mvlx1S7oZES3w!J!J!Q&7185d
 Z&lx1CS9d9nE4!k&X&MY7!&1!J!x&jdnjdS3odS!N&mmx1C2wEc!G&150Nx4!n&2o!j&43r!U&0777d
 ]&2AY2A776ddT4oS3oSnMVC00VV0RRR45E42063rNz&v7UX&UOzF!F!J![&44ETCnVn!a&1CDN!Y&0M
 V1c&j2AYdjmMdjjd!o&1r!M){( )T 0 4 3 r put T(/)g{T(9)g{cvn}{cvi}J}{($)g[]J}J
 cvx}forall/moveto/p/floor/w/div/S/add 29 H[{[{]setgray fill}for Y}for showpage
 EOF
 ) ) )

Windows specific notes

Use of UTF8 encoded strings for pathnames is not supported. Windows uses a 16-bit UNICODE encoding with special system calls for wide-character support. Only single-byte string encoding can be used.


Previous: Module (chicken pretty-print)

Next: Module (chicken process signal)

Contents »