Operating System Interface

$Revision: 5.0.2.4 $

The document introduction.htm provides an overview of the Allegro CL documentation with links to all major documents. The document index.htm is an index with pointers to every documented object (operators, variables, etc.) The revision number of this document is below the title. These documents may be revised from time to time between releases.

1.0 Operating-system interface
2.0 Subprocess functions
3.0 Environment functions
4.0 Temporary directory and files
5.0 Accessing command-line arguments
6.0 Polling and setting environment variables

1.0 Operating-system interface

This chapter describes some functions in Allegro CL that interact with the host operating system. These functions include those providing control and interaction with subprocesses, determination and change of the current working directory, and saving the state of a Lisp session.

2.0 Subprocess functions

Allegro CL has the ability to run UNIX and Windows child processes controlled from Lisp. Starting a subprocess and communicating with it are slower than using the foreign function interface to accomplish the same task, but it is sometimes unavoidable. Creating very many simultaneous subprocesses is not recommended.

Subprocesses can be started with excl:run-shell-command and with excl:shell. If excl:run-shell-command is called with the wait keyword argument nil, sys:reap-os-subprocess (or sys:os-wait) must be called to clear the process from the system. Failure to do this will eventually cause the system to be unable to create new processes.

Here are a couple of examples, both on Unix, of excl:run-shell-command. In the first, we simply have excl:run-shell-command execute a simple command (who).

USER(1): (run-shell-command "who")
sdj       ttyp0       Aug 18 16:08 (rubix)
adam      ttyp2       Aug 18 16:17 (rubix)
dm        ttyp4       Aug 19 10:24 (rubix)
0
USER(2):

The second example is more complicated. We cause excl:run-shell-command to spawn a shell and then we communicate with the shell via the stream set up by excl:run-shell-command.

;; First we define a function to read the output from the shell. This
;; function is pretty simple -- it reads characters and prints them
;; out but it does show how a more useful function could be implemented.
USER(24): (defun get-from-shell (stream)
             (do ((ch (read-char-no-hang stream)
                      (read-char-no-hang stream)))
                  ((null ch))
               (write-char ch)))
GET-FROM-SHELL
;; Now we initiate the shell:
USER(25): (setq shell-stream (excl:run-shell-command "csh"
                                 :input :stream
                                 :output :stream
                                 :wait nil))
#<EXCL::BIDIRECTIONAL-TERMINAL-STREAM @ #x10a4aa6>
USER(26): (format shell-stream "who~%")
NIL
USER(27): (force-output shell-stream)
NIL
USER(28): (get-from-shell shell-stream)
rlogin ttya Aug 19 07:06
rlogin ttyb Aug 19 08:26
sdj ttyp0 Aug 18 16:08 (rubix)
cheetham ttyp1 Aug 18 17:17 (frozen)
adam ttyp2 Aug 18 16:17 (rubix)
NIL
;; We exit the shell:
USER(29): (format shell-stream "exit~%")
NIL
;; and close the stream.
USER(30): (close shell-stream)
T
;; We call sys:reap-os-subprocess because we called
;; run-shell-command with :wait nil:
USER(31): (sys:reap-os-subprocess)
0
27201
USER(32):

3.0 Environment functions

The following functions provide information about directories in the system:

Name Arguments Notes
excl:chdir &optional pathname Make pathname the current directory. If unspecified, make the current user's home directory the current directory (UNIX) or make c:\ the current directory (Windows). See the full description as the function has some oddities. See also the example below.
excl:current-directory   Returns the current directory.
excl:username-to-home-directory name On Unix, returns the home directory of the user named by the argument. On Windows, return c:\ unconditionally.

Examples using excl:chdir. The current users home directory is /usr/tech/doe/. The directory /usr/tech/doe/tmp/ exists. The allegro directory for the Lisp is /acl5.0/home/.

user(15): (chdir) ;; no argument: change to user home directory
"/usr/tech/doe/"
user(16): (chdir "sys:") ;; a string naming a logical pathname which translates
;; to the Lisp home directory.
"/acl5.0/home/"
user(17): (chdir)
"/usr/tech/doe/"
user(18): (chdir "tmp") ;; change to the tmp/ subdirectory
"tmp/"
user(19): (chdir (make-pathname :directory "tmp")) ;; The absolute directory
;; /tmp/
"/tmp/"
user(20): (chdir)
"/usr/tech/doe/"
user(21):

The following functions manipulate files and/or directories:

Function Arguments Notes
excl:copy-directory from-dir to-dir &key quiet &allow-other-keys Copies from-dir to to-dir. Accepts sys:copy-file keywords for copying files in the directory being copied.
sys:copy-file from-pathname to-pathname &key link-ok preserve-symbolic-links element-type preserve-time Copies from-pathname to to-pathname preserving features as specified by keyword arguments.
excl:delete-directory pathname Deletes the directory named by pathname, which must be an empty directory.
excl:delete-directory-and-files directory &key if-does-not-exist quiet Deletes the directory named by directory and all of its subdirectories and files.
excl:directory-size dirname &key roundup Returns the size in bytes of the directory named by dirname, rounded up to a multiple of roundup.
excl:make-directory pathname &optional mode Creates a directory named by pathname.

4.0 Temporary directory and files

Allegro CL may need to write temporary files while it runs. The first function following returns the directory used by the current running Lisp is using as its temporary directory. The second returns an unused filename in that directory.

Name Arguments Notes
system:temporary-directory   Returns the pathname of the temporary directory used by the current running Lisp for writing temporary files.
system:make-temp-file-name &optional (prefix "temp") (directory (sys:temporary-directory)) Returns an unused filename but does not create the file (so the same name could be returned by a subsequent call if the file is not created).

5.0 Accessing command-line arguments

Allegro CL may be called with any number of arguments on the command line. Some of these arguments are used by Allegro CL itself (to suppress reading of initialization files, for example) and others are simply collected and made available to the running Lisp.

Lisp uses `--' as a delimiter between arguments used by Allegro CL when starting up and arguments simply collected and made available after Lisp has started. All arguments before the first appearance of `--' are used by Allegro CL and an improper arguments before that marker will cause Allegro CL to signal a warning. All arguments after the first appearance of `--' are ignored by Allegro CL when starting up and are available after startup, accessible with the following functions. Note that the arguments before the `--' are also available with these functions. Note too that Lisp can be created so it ignores all command-line arguments (simply making all available after startup). This will happen if an image is created with excl:dumplisp with :ignore-command-line-arguments specified as true.

Further, if no -I argument is provided (to specify an image file, so the image file with the same name and in the same directory as the executable is used), the command line will look like a -I argument was specified, as shown in the examples.

See startup.htm for information on command-line-arguments. The functions that access command-line arguments are:

Name Arguments Notes
system:command-line-argument (n &key application) Returns the value of the nth command-line arguments.
system:command-line-arguments (&key application) Returns a list of all command-line arguments.
system:command-line-argument-count (&key application) Returns the number of command-line arguments.

The application keyword argument, if t (the default) leaves out any arguments before the first `--' and the first `--'. If nil, all arguments are considered.

The purpose of these functions is to allow you to customize the running of Lisp when the image is invoked. As a simple example, suppose you invoke Lisp as follows:

lisp -qq -- foo -batch bar

Here, lisp is the name of the Allegro CL executable. Note first that Lisp will not run in batch mode since the -batch appears after `--'. However, no initialization file will be read since the -qq argument appears before the `--'. See startup.htm for more information on command line arguments which affect how Lisp starts up. As we said above, the command line arguments will show -I <image.dxl> arguments even though they were not specified.

Here is what the various command line functions return given that command line:

(sys:command-line-argument 0) [returns] "lisp"
(sys:command-line-argument 1) [returns] "foo"
(sys:command-line-argument 1 :application nil) [returns] "-I"
(sys:command-line-arguments) [returns] ("lisp" "foo" "-batch" "bar")
(sys:command-line-arguments :application nil)
   [returns] ("lisp" "-I" "lisp.dxl" "-qq" "--" "foo" "-batch" "bar")
(sys:command-line-argument-count) [returns] 4
(sys:command-line-argument-count :application nil) [returns] 8

You may use this information as you see fit. One possible use, for example, is to have some function defined and run (perhaps in an initialization file) which takes some action (such as loading specific files) based on the values of the arguments.

6.0 Polling and setting environment variables

The setf'able function sys:getenv returns (and with setf sets) the value of an environment variable.

;; The current values of the environment variable on your system may,
;; of course, be different from what appears in this example.
user(2): (sys:getenv "SHELL")
"/bin/csh"
user(3): (setf (sys:getenv "SHELL") "/bin/sh")
"/bin/sh"
user(4): (sys:getenv "SHELL")
"/bin/sh"

Warning: When you use setf with sys:getenv to set an environment variable, the string specifying the new value is stored in malloc'ed space and that space cannot be freed (in any practical way). This creates a small memory leak in the system, but it should only be significant if you set many, many environment variables.

Note that there is no pre-defined, programmatic way to unset an environment variable from within Lisp. It is an error to setf sys:getenv to anything other than a string and the effect of doing so is undefined (an error is typically not signaled but the behavior is likely not what is intended). Specifically.

(setf (sys:getenv "VAR") nil)

does not unset VAR in the environment.

Copyright (C) 1998-1999, Franz Inc., Berkeley, CA. All Rights Reserved.