ToCDocOverviewCGDocRelNotesIndexPermutedIndex
Allegro CL version 6.2
Unrevised from 6.1

Operating System Interface

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:

Name Arguments Notes
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.
current-directory Returns the current directory.
username-to-home-directory name On 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/acl61/.

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/acl61/"
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 provide information about or 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 preserve-symbolic-links element-type preserve-time Copies 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-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:file-directory-p filespec Returns true if argument names a directory.
excl:make-directory pathname &optional mode Creates a directory named by pathname.
excl:map-over-directory function directory &key filter prune-directories include-directories file-type recurse Applies function to the entries in directory, with keywords allowing for finer control.


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.

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 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:

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 leaves out the `--' (so if `--' doesn't appear, the list containing only the executable name is returned). 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:

mlisp -qq -- foo -batch bar 

Here, mlisp 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] "mlisp"
(sys:command-line-argument 1) [returns] "foo"
(sys:command-line-argument 1 :application nil) [returns] "-I"
(sys:command-line-arguments) [returns] ("mlisp" "foo"
"-batch" "bar")
(sys:command-line-arguments :application nil) 
   [returns] ("mlisp" "-I" "mlisp.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-2002, Franz Inc. Oakland, CA., USA. All rights reserved.
Documentation for Allegro CL version 6.2. This page was not revised from the 6.1 page.
Created 2002.2.26.

ToCDocOverviewCGDocRelNotesIndexPermutedIndex
Allegro CL version 6.2
Unrevised from 6.1