3.2 Operating System Interface


3.2.1 Command line arguments

Variable: string ext:*help-message*

Command line help message. Initial value is ECL help message. This variable contains the help message which is output when ECL is invoked with the --help.

Variable: list-of-pathname-designators ext:*lisp-init-file-list*

ECL initialization files. Initial value is '("~/.ecl" "~/.eclrc"). This variable contains the names of initialization files that are loaded by ECL or embedding programs. The loading of initialization files happens automatically in ECL unless invoked with the option --norc. Whether initialization files are loaded or not is controlled by the command line options rules, as described in ext:process-command-args.

Variable: list-of-lists ext:+default-command-arg-rules+

ECL command line options. This constant contains a list of rules for parsing the command line arguments. This list is made of all the options which ECL accepts by default. It can be passed as first argument to ext:process-command-args, and you can use it as a starting point to extend ECL.

Function: ext:command-args

Original list of command line arguments. This function returns the list of command line arguments passed to either ECL or the program it was embedded in. The output is a list of strings and it corresponds to the argv vector in a C program. Typically, the first argument is the name of the program as it was invoked. You should not count on the filename to be resolved.

Function: ext:process-command-args &key args rules
args

A list of strings. Defaults to the output of ext:command-args.

rules

A list of lists. Defaults to the value of ext:+default-command-arg-rules+.

This function processes the command line arguments passed to either ECL or the program that embeds it. It uses the list of rules rules, which has the following syntax:

(option-name nargs template [:stop | :noloadrc | :loadrc]*)

option-name

A string with the option prefix as typed by the user. For instance --help, -?, --compile, etc.

nargs

A non-negative integer denoting the number of arguments taken by this option.

template

A lisp form, not evaluated, where numbers from 0 to nargs will be replaced by the corresponding option argument.

:stop

If present, parsing of arguments stops after this option is found and processed. The list of remaining arguments is passed to the rule. ECL’s top-level uses this option with the -- command line option to set ext:*unprocessed-ecl-command-args* to the list of remaining arguments.

:noloadrc, :loadrc

Determine whether the lisp initialization files in ext:*lisp-init-file-list* will be loaded before processing all forms.

ext:process-command-args works as follows. First of all, it parses all the command line arguments, except for the first one, which is assumed to contain the program name. Each of these arguments is matched against the rules, sequentially, until one of the patterns succeeds.

A special name *default*, matches any unknown command line option. If there is no *default* rule and no match is found, an error is signaled. For each rule that succeeds, the function constructs a lisp statement using the template.

After all arguments have been processed, ext:process-command-args, and there were no occurrences of :noloadrc, the first existing file listed in ext:*lisp-init-file-list* will be loaded. Finally, the list of lisp statements will be evaluated.

The following piece of code implements the ls command using lisp. Instructions for building this program are found under examples/cmdline/ls.lsp.

(setq ext:*help-message* "
ls [--help | -?] filename*
     Lists the file that match the given patterns.
")

(defun print-directory (pathnames)
  (format t "~{~A~%~}"
          (mapcar #'(lambda (x) (enough-namestring x (si::getcwd)))
                  (mapcan #'directory (or pathnames '("*.*" "*/"))))))

(defconstant +ls-rules+
  '(("--help" 0 (progn (princ ext:*help-message* *standard-output*) (ext:quit 0)))
    ("-?" 0 (progn (princ ext:*help-message* *standard-output*) (ext:quit 0)))
    ("*DEFAULT*" 1 (print-directory 1) :stop)))

(let ((ext:*lisp-init-file-list* NIL)) ; No initialization files
  (handler-case (ext:process-command-args :rules +ls-rules+)
                (error (c)
                       (princ ext:*help-message* *error-output*)
                       (ext:quit 1))))
(ext:quit 0)

3.2.2 External processes

ECL provides several facilities for invoking and communicating with external processes. If one just wishes to execute some program, without caring for its output, then probably ext:system is the best function. In all other cases it is preferable to use ext:run-program, which opens pipes to communicate with the program and manipulate it while it runs on the background.

External process is a structure created with ext:run-program (returned as third value). It is programmer responsibility, to call ext:external-process-wait on finished processes, however during garbage collection object will be finalized.

Function: ext:external-process-pid process

Returns process PID or nil if already finished.

Function: ext:external-process-status process

Updates process status. ext:external-process-status calls ext:external-process-wait if process has not finished yet (non-blocking call). Returns two values:

status - member of (:abort :error :exited :signaled :stopped :resumed :running)

code - if process exited it is a returned value, if terminated it is a signal code. Otherwise NIL.

Function: ext:external-process-wait process wait

If the second argument is non-NIL, function blocks until external process is finished. Otherwise status is updated. Returns two values (see ext:external-process-status).

Function: ext:terminate-process process &optional force

Terminates external process. May signal an error if the process has already finished.

Function: ext:external-process-input process
Function: ext:external-process-output process
Function: ext:external-process-error-stream process

Process stream accessors (read-only).

Function: ext:run-program command argv &key input output error wait environ if-input-does-not-exist if-output-exists if-error-exists external-format #+windows escape-arguments

ext:run-program creates a new process specified by the command argument. argv 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).

ext:run-program will return three values - two-way stream for communication, return code or nil (if process is called asynchronously), and ext:external-process object holding process state.

It is programmer responsibility to call ext:external-process-wait on finished process, however ECL associates finalizer with the object calling it when the object is garbage collected. If process didn’t finish but is not referenced, finalizer will be invoked once more during next garbage collection.

The &key arguments have the following meanings:

input

Either t, nil, a pathname, a string, a stream or :stream. If t the standard input for the current process is inherited. If nil, /dev/null is used. If a pathname (or a string), 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 ext:external-process-input slot is filled in with a stream that sends its output to the process. Defaults to :stream.

if-input-does-not-exist

Can be one of: :error to generate an error :create to create an empty file nil (the default) to return nil from ext:run-program

output

Either t, nil, a pathname, a string, a stream, or :stream. If t, the standard output for the current process is inherited. If nil, /dev/null is used. If a pathname (or as string), the file so specified is used. If a stream, all the output from the process is written to this stream. If :stream, the ext:external-process-output slot is filled in with a stream that can be read to get the output. Defaults to :stream.

if-output-exists

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 or nil to return nil from ext:run-program.

error

Same as :output, except that :error can also be specified as :output in which case all error output is routed to the same place as normal output. Defaults to :output.

if-error-exists

Same as :if-output-exists.

wait

If non-nil (default), wait until the created process finishes. If nil, continue running Lisp until the program finishes.

environ

A list of STRINGs describing the new Unix environment (as in "man environ"). The default is to copy the environment of the current process. To extend existing environment (instead of replacing it), use :environ (append *my-env* (ext:environ)).

If non-nil environ argument is supplied, then first argument to ext:run-program, command, must be full path to the file.

external-format

The external-format to use for :input, :output, and :error STREAMs.

Windows specific options:

escape-arguments

Controls escaping of the arguments passed to CreateProcess.


3.2.3 FIFO files (named pipes)

Named pipe (known as fifo) may be created on UNIX with a shell command mkfifo. They can be opened in non-blocking mode by using :nonblock t option for open. ext:file-kind will return for such file :fifo. Since it is impossible to guess how many characters are available in this special file file-length function will return nil.


3.2.4 Operating System Interface Reference

Function: ext:system command

Run shell command ignoring its output. Uses fork.

Function: ext:make-pipe

Creates a pipe and wraps it in a two way stream.

Function: ext:quit &optional exit-code kill-all-threads

This function abruptly stops the execution of the program in which ECL is embedded. Depending on the platform, several other functions will be invoked to free resources, close loaded modules, etc.

The exit code is the code seen by the parent process that invoked this program. Normally a code other than zero denotes an error.

If kill-all-threads is non-nil, tries to gently kill and join with running threads.

Function: ext:environ
Function: ext:getenv variable
Function: ext:setenv variable value

Environment accessors.

Function: ext:getpid
Function: ext:getuid
Function: ext:getcwd &optional (change-default-pathname-defaults NIL)
Function: ext:chdir directory &optional (change-default-pathname-defaults T)
Function: ext:file-kind filename follow-symlinks-p
Function: ext:copy-file filename destination-filename
Function: ext:chmod filename mode

Common operating system functions.