Operating System Interface

The index for the Allegro CL Documentation is in index.htm. The documentation is described in introduction.htm.

This document contains the following sections:

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 run-shell-command and with shell. If run-shell-command is called with the wait keyword argument nil, reap-os-subprocess (or 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. Further, the streams opened by run-shell-command must be closed by the program. The system will not close them automatically.

Here are a couple of examples, both on Unix, of run-shell-command. In the first, we simply have 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 run-shell-command to spawn a shell and then we communicate with the shell via the stream set up by 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:

NameArgumentsNotes
chdir&optional pathnameMake 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.
current-directoryReturns the current directory.
username-to-home-directorynameOn Unix, returns the home directory of the user named by the argument. On Windows, uses the value of the HOME environment variable; uses C:\\ if that variable is not set.

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 (in this example) /usr/acl60/.

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.
"/usr/acl60/"
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:

FunctionArgumentsNotes
excl:copy-directoryfrom-dir to-dir &key quiet &allow-other-keysCopies from-dir to to-dir. Accepts sys:copy-file keywords for copying files in the directory being copied.
copy-filefrom-pathname to-pathname &key link preserve-symbolic-links element-type preserve-timeCopies from-pathname to to-pathname preserving features as specified by keyword arguments. Note:link argument was called link-ok in releases 5.0.1 and earlier. The default value has also changed. See the description page for details.
excl:delete-directorypathnameDeletes the directory named by pathname, which must be an empty directory.
excl:delete-directory-and-filesdirectory &key if-does-not-exist quietDeletes the directory named by directory and all of its subdirectories and files.
excl:directory-sizedirname &key roundupReturns the size in bytes of the directory named by dirname, rounded up to a multiple of roundup.
excl:make-directorypathname&optional modeCreates 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 as its temporary directory. The second returns an unused filename in that directory.

NameArgumentsNotes
system:temporary-directoryReturns 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 any 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 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 Command line arguments in startup.htm for information on command-line-arguments. The functions that access command-line arguments are:

NameArgumentsNotes
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 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-2000, Franz Inc. Berkeley, CA., USA. All rights reserved. Created 2000.10.5.