   This file documents the MIT Scheme system.

   Copyright (C) 1988-2002 Massachusetts Institute of Technology

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the section entitled "GNU
Free Documentation License".

Operations on Pathnames
-----------------------

 - procedure: pathname? object
     Returns `#t' if OBJECT is a pathname; otherwise returns `#f'.

 - procedure: pathname=? pathname1 pathname2
     Returns `#t' if PATHNAME1 is equivalent to PATHNAME2; otherwise
     returns `#f'.  Pathnames are equivalent if all of their components
     are equivalent, hence two pathnames that are equivalent must
     identify the same file or equivalent partial pathnames.  However,
     the converse is not true: non-equivalent pathnames may specify the
     same file (e.g. via absolute and relative directory components),
     and pathnames that specify no file at all (e.g. name and directory
     components unspecified) may be equivalent.

 - procedure: pathname-absolute? pathname
     Returns `#t' if PATHNAME is an absolute rather than relative
     pathname object; otherwise returns `#f'.  Specifically, this
     procedure returns `#t' when the directory component of PATHNAME is
     a list starting with the symbol `absolute', and returns `#f' in
     all other cases.  All pathnames are either absolute or relative,
     so if this procedure returns `#f', the argument is a relative
     pathname.

 - procedure: directory-pathname? pathname
     Returns `#t' if PATHNAME has only directory components and no file
     components.  This is roughly equivalent to

          (define (directory-pathname? pathname)
            (string-null? (file-namestring pathname)))

     except that it is faster.

 - procedure: pathname-wild? pathname
     Returns `#t' if PATHNAME contains any wildcard components;
     otherwise returns `#f'.

 - procedure: merge-pathnames pathname [defaults [default-version]]
     Returns a pathname whose components are obtained by combining
     those of PATHNAME and DEFAULTS.  DEFAULTS defaults to the value of
     `*default-pathname-defaults*' and DEFAULT-VERSION defaults to
     `newest'.

     The pathnames are combined by components: if PATHNAME has a
     non-missing component, that is the resulting component, otherwise
     the component from DEFAULTS is used.  The default version can be
     `#f' to preserve the information that the component was missing
     from PATHNAME.  The directory component is handled specially: if
     both pathnames have directory components that are lists, and the
     directory component from PATHNAME is relative (i.e. starts with
     `relative'), then the resulting directory component is formed by
     appending PATHNAME's component to DEFAULTS's component.  For
     example:

          (define path1 (->pathname "scheme/foo.scm"))
          (define path2 (->pathname "/usr/morris"))
          path1
               =>  #[pathname 74 "scheme/foo.scm"]
          path2
               =>  #[pathname 75 "/usr/morris"]
          (merge-pathnames path1 path2)
               =>  #[pathname 76 "/usr/scheme/foo.scm"]
          (merge-pathnames path2 path1)
               =>  #[pathname 77 "/usr/morris.scm"]

     The merging rules for the version are more complex and depend on
     whether PATHNAME specifies a name.  If PATHNAME does not specify a
     name, then the version, if not provided, will come from DEFAULTS.
     However, if PATHNAME does specify a name then the version is not
     affected by DEFAULTS.  The reason is that the version "belongs to"
     some other file name and is unlikely to have anything to do with
     the new one.  Finally, if this process leaves the version missing,
     then DEFAULT-VERSION is used.

     The net effect is that if the user supplies just a name, then the
     host, device, directory and type will come from DEFAULTS, but the
     version will come from DEFAULT-VERSION.  If the user supplies
     nothing, or just a directory, the name, type and version will come
     over from DEFAULTS together.

 - variable: *default-pathname-defaults*
     This is the default pathname-defaults pathname; if any pathname
     primitive that needs a set of defaults is not given one, it uses
     this one.  `set-working-directory-pathname!' sets this variable to
     a new value, computed by merging the new working directory with
     the variable's old value.

 - procedure: pathname-default pathname device directory name type
          version
     This procedure defaults all of the components of PATHNAME
     simultaneously.  It could have been defined by:

          (define (pathname-default pathname
                                    device directory name type version)
            (make-pathname (pathname-host pathname)
                           (or (pathname-device pathname) device)
                           (or (pathname-directory pathname) directory)
                           (or (pathname-name pathname) name)
                           (or (pathname-type pathname) type)
                           (or (pathname-version pathname) version)))

 - procedure: file-namestring pathname
 - procedure: directory-namestring pathname
 - procedure: host-namestring pathname
 - procedure: enough-namestring pathname [defaults]
     These procedures return a string corresponding to a subset of the
     PATHNAME information.  `file-namestring' returns a string
     representing just the NAME, TYPE and VERSION components of
     PATHNAME; the result of `directory-namestring' represents just the
     HOST, DEVICE, and DIRECTORY components; and `host-namestring'
     returns a string for just the HOST portion.

     `enough-namestring' takes another argument, DEFAULTS.  It returns
     an abbreviated namestring that is just sufficient to identify the
     file named by PATHNAME when considered relative to the DEFAULTS
     (which defaults to `*default-pathname-defaults*').

          (file-namestring "/usr/morris/minor.van")
               =>  "minor.van"
          (directory-namestring "/usr/morris/minor.van")
               =>  "/usr/morris/"
          (enough-namestring "/usr/morris/men")
               =>  "men"      ;perhaps

 - procedure: file-pathname pathname
 - procedure: directory-pathname pathname
 - procedure: enough-pathname pathname [defaults]
     These procedures return a pathname corresponding to a subset of the
     PATHNAME information.  `file-pathname' returns a pathname with
     just the NAME, TYPE and VERSION components of PATHNAME.  The
     result of `directory-pathname' is a pathname containing the HOST,
     DEVICE and DIRECTORY components of PATHNAME.

     `enough-pathname' takes another argument, DEFAULTS.  It returns an
     abbreviated pathname that is just sufficient to identify the file
     named by PATHNAME when considered relative to the DEFAULTS (which
     defaults to `*default-pathname-defaults*').

     These procedures are similar to `file-namestring',
     `directory-namestring' and `enough-namestring', but they return
     pathnames instead of strings.

 - procedure: directory-pathname-as-file pathname
     Returns a pathname that is equivalent to PATHNAME, but in which
     the directory component is represented as a file.  The last
     directory is removed from the directory component and converted
     into name and type components.  This is the inverse operation to
     `pathname-as-directory'.

          (directory-pathname-as-file (->pathname "/usr/blisp/"))
               =>  #[pathname "/usr/blisp"]

 - procedure: pathname-as-directory pathname
     Returns a pathname that is equivalent to PATHNAME, but in which
     any file components have been converted to a directory component.
     If PATHNAME does not have name, type, or version components, it is
     returned without modification.  Otherwise, these file components
     are converted into a string, and the string is added to the end of
     the list of directory components.  This is the inverse operation to
     `directory-pathname-as-file'.

          (pathname-as-directory (->pathname "/usr/blisp/rel5"))
               =>  #[pathname "/usr/blisp/rel5/"]

Miscellaneous Pathname Procedures
---------------------------------

   This section gives some standard operations on host objects, and some
procedures that return some useful pathnames.

 - variable: local-host
     This variable has as its value the host object that describes the
     local host's file system.

 - procedure: host? object
     Returns `#t' if OBJECT is a pathname host; otherwise returns `#f'.

 - procedure: host=? host1 host2
     Returns `#t' if HOST1 and HOST2 denote the same pathname host;
     otherwise returns `#f'.

 - procedure: init-file-pathname [host]
     Returns a pathname for the user's initialization file on HOST.
     The HOST argument defaults to the value of `local-host'.  If the
     initialization file does not exist this procedure returns `#f'.

     Under unix, the init file is called `.scheme.init'; under Windows
     and OS/2, the init file is called `scheme.ini'.  In either case,
     it is located in the user's home directory, which is computed by
     `user-homedir-pathname'.

 - procedure: user-homedir-pathname [host]
     Returns a pathname for the user's "home directory" on HOST.  The
     HOST argument defaults to the value of `local-host'.  The concept
     of a "home directory" is itself somewhat implementation-dependent,
     but it should be the place where the user keeps personal files,
     such as initialization files and mail.

     Under unix, the user's home directory is specified by the `HOME'
     environment variable.  If this variable is undefined, the user
     name is computed using the `getlogin' system call, or if that
     fails, the `getuid' system call.  The resulting user name is
     passed to the `getpwnam' system call to obtain the home directory.

     Under OS/2, several heuristics are tried to find the user's home
     directory.  First, if the environment variable `HOME' is defined,
     that is the home directory.  If `HOME' is undefined, but the
     `USERDIR' and `USER' environment variables are defined and the
     directory `%USERDIR%\%USER%' exists, then it is used.  Failing
     that, if the directory `%USER%' exists on the OS/2 system drive,
     then it is used.  As a last resort, the OS/2 system drive is the
     home directory.

     Like OS/2, the Windows implementation uses heuristics based on
     environment variables.  The user's home directory is computed by
     examining several environment variables, in the following order:

        * `HOMEDRIVE' and `HOMEPATH' are both defined and
          `%HOMEDRIVE%%HOMEPATH%' is an existing directory.  (These
          variables are automatically defined by Windows NT.)

        * `HOME' is defined and `%HOME%' is an existing directory.

        * `USERDIR' and `USERNAME' are defined and
          `%USERDIR%\%USERNAME%' is an existing directory.

        * `USERDIR' and `USER' are defined and `%USERDIR%\%USER%' is an
          existing directory.

        * `USERNAME' is defined and `%USERNAME%' is an existing
          directory on the Windows system drive.

        * `USER' is defined and `%USER%' is an existing directory on the
          Windows system drive.

        * Finally, if all else fails, the Windows system drive is used
          as the home directory.

 - procedure: system-library-pathname pathname
     Locates PATHNAME in MIT Scheme's system library directory.  An
     error of type `condition-type:file-operation-error' is signalled if
     PATHNAME cannot be located on the library search path.

          (system-library-pathname "compiler.com")
            => #[pathname 45 "/usr/local/lib/mit-scheme/compiler.com"]

 - procedure: system-library-directory-pathname pathname
     Locates the pathname of an MIT Scheme system library directory.  An
     error of type `condition-type:file-operation-error' is signalled if
     PATHNAME cannot be located on the library search path.

          (system-library-directory-pathname "options")
               => #[pathname 44 "/usr/local/lib/mit-scheme/options/"]

Working Directory
=================

   When MIT Scheme is started, the "current working directory" (or
simply, "working directory") is initialized in an operating-system
dependent manner; usually, it is the directory in which Scheme was
invoked.  The working directory can be determined from within Scheme by
calling the `pwd' procedure, and changed by calling the `cd' procedure.
Each REP loop has its own working directory, and inferior REP loops
initialize their working directory from the value in effect in their
superior at the time they are created.

 - procedure: working-directory-pathname
 - procedure: pwd
     Returns the current working directory as a pathname that has no
     name, type, or version components, just host, device, and directory
     components.  `pwd' is an alias for `working-directory-pathname';
     the long name is intended for programs and the short name for
     interactive use.

 - procedure: set-working-directory-pathname! filename
 - procedure: cd filename
     Makes FILENAME the current working directory and returns the new
     current working directory as a pathname.  FILENAME is coerced to a
     pathname using `pathname-as-directory'.  `cd' is an alias for
     `set-working-directory-pathname!'; the long name is intended for
     programs and the short name for interactive use.

     Additionally, `set-working-directory-pathname!' modifies the value
     of
     `*default-pathname-defaults*' by merging the new working directory
     into it.

     When this procedure is executed in the top-level REP loop, it
     changes the working directory of the running Scheme executable.

          (set-working-directory-pathname! "/usr/morris/blisp")
               =>  #[pathname "/usr/morris/blisp/"]
          (set-working-directory-pathname! "~")
               =>  #[pathname "/usr/morris/"]

     This procedure signals an error if FILENAME does not refer to an
     existing directory.

     If FILENAME describes a relative rather than absolute pathname,
     this procedure interprets it as relative to the current working
     directory, before changing the working directory.

          (working-directory-pathname)
               =>  #[pathname "/usr/morris/"]
          (set-working-directory-pathname! "foo")
               =>  #[pathname "/usr/morris/foo/"]

 - procedure: with-working-directory-pathname filename thunk
     This procedure temporarily rebinds the current working directory to
     FILENAME, invokes THUNK (a procedure of no arguments), then
     restores the previous working directory and returns the value
     yielded by THUNK.  FILENAME is coerced to a pathname using
     `pathname-as-directory'.  In addition to binding the working
     directory, `with-working-directory-pathname' also binds the
     variable `*default-pathname-defaults*', merging the old value of
     that variable with the new working directory pathname.  Both
     bindings are performed in exactly the same way as dynamic binding
     of a variable (see Dynamic Binding).

File Manipulation
=================

   This section describes procedures that manipulate files and
directories.  Any of these procedures can signal a number of errors for
many reasons.  The specifics of these errors are much too
operating-system dependent to document here.  However, if such an error
is signalled by one of these procedures, it will be of type
`condition-type:file-operation-error'.

 - procedure: file-exists? filename
 - procedure: file-exists-direct? filename
 - procedure: file-exists-indirect? filename
     These procedures return `#t' if FILENAME is an existing file or
     directory; otherwise they return `#f'.  In operating systems that
     support symbolic links, if the file is a symbolic link,
     `file-exists-direct?' tests for the existence of the link, while
     `file-exists-indirect?' and `file-exists?' test for the existence
     of the file pointed to by the link.

 - procedure: copy-file source-filename target-filename
     Makes a copy of the file named by SOURCE-FILENAME.  The copy is
     performed by creating a new file called TARGET-FILENAME, and
     filling it with the same data as SOURCE-FILENAME.

 - procedure: rename-file source-filename target-filename
     Changes the name of SOURCE-FILENAME to be TARGET-FILENAME.  In the
     unix implementation, this will not rename across file systems.

 - procedure: delete-file filename
     Deletes the file named FILENAME.

 - procedure: delete-file-no-errors filename
     Like `delete-file', but returns a boolean value indicating whether
     an error occurred during the deletion.  If no errors occurred, `#t'
     is returned.  If an error of type `condition-type:file-error' or
     `condition-type:port-error' is signalled, `#f' is returned.

 - procedure: hard-link-file source-filename target-filename
     Makes a hard link from SOURCE-FILENAME to TARGET-FILENAME.  This
     operation gives the file specified by SOURCE-FILENAME a new name,
     in addition to the old name.

     This currently works only on unix systems.  It is further
     restricted to work only when  SOURCE-FILENAME and TARGET-FILENAME
     refer to names in the same file system.

 - procedure: soft-link-file source-filename target-filename
     Creates a new soft link called TARGET-FILENAME that points at the
     file SOURCE-FILENAME.  (Soft links are also sometimes called
     "symbolic" links.)  Note that SOURCE-FILENAME will be interpreted
     as a string (although you may specify it as a pathname object, if
     you wish).  The contents of this string will be stored in the file
     system as the soft link.  When a file operation attempts to open
     the link, the contents of the link are interpreted relative to the
     link's location at that time.

     This currently works only on unix systems.

 - procedure: make-directory filename
     Creates a new directory named FILENAME.  Signals an error if
     FILENAME already exists, or if the directory cannot be created.

 - procedure: delete-directory filename
     Deletes the directory named FILENAME.  Signals an error if the
     directory does not exist, is not a directory, or contains any files
     or subdirectories.

 - procedure: ->truename filename
     This procedure attempts to discover and return the "true name" of
     the file associated with FILENAME within the file system.  An
     error of type `condition-type:file-operation-error' is signalled
     if the appropriate file cannot be located within the file system.

 - procedure: call-with-temporary-file-pathname procedure
     Calls `temporary-file-pathname' to create a temporary file, then
     calls PROCEDURE with one argument, the pathname referring to that
     file.  When PROCEDURE returns, if the temporary file still exists,
     it is deleted; then, the value yielded by PROCEDURE is returned.
     If PROCEDURE escapes from its continuation, and the file still
     exists, it is deleted.

 - procedure: temporary-file-pathname [directory]
     Creates a new empty temporary file and returns a pathname
     referring to it.  The temporary file is created with Scheme's
     default permissions, so barring unusual circumstances it can be
     opened for input and/or output without error.  The temporary file
     will remain in existence until explicitly deleted.  If the file
     still exists when the Scheme process terminates, it will be
     deleted.

     If DIRECTORY is specified, the temporary file will be stored
     there.  If it is not specified, or if it is `#f', the temporary
     file will be stored in the directory returned by
     `temporary-directory-pathname'.

 - procedure: temporary-directory-pathname
     Returns the pathname of an existing directory that can be used to
     store temporary files.  These directory names are tried, in order,
     until a writeable directory is found:

        * The directories specified by the environment variables
          `TMPDIR', `TEMP', or `TMP'.

        * Under unix, the directories `/var/tmp', `/usr/tmp', or `/tmp'.

        * Under OS/2 or Windows, the following directories on the
          system drive: `\temp', `\tmp', or `\'.

        * Under OS/2 or Windows, the current directory, as specified by
          `*default-pathname-defaults*'.

 - procedure: file-directory? filename
     Returns `#t' if the file named FILENAME exists and is a directory.
     Otherwise returns `#f'.  In operating systems that support
     symbolic links, if FILENAME names a symbolic link, this examines
     the file linked to, not the link itself.

     This is equivalent to

          (eq? 'directory (file-type-indirect FILENAME))

 - procedure: file-regular? filename
     Returns `#t' if the file named FILENAME exists and is a regular
     file (i.e. not a directory, symbolic link, device file, etc.).
     Otherwise returns `#f'.  In operating systems that support symbolic
     links, if FILENAME names a symbolic link, this examines the file
     linked to, not the link itself.

     This is equivalent to

          (eq? 'regular (file-type-indirect FILENAME))

 - procedure: file-symbolic-link? filename
     In operating systems that support symbolic links, if the file named
     FILENAME exists and is a symbolic link, this procedure returns the
     contents of the symbolic link as a newly allocated string.  The
     returned value is the name of the file that the symbolic link
     points to and must be interpreted relative to the directory of
     FILENAME.  If FILENAME either does not exist or is not a symbolic
     link, or if the operating system does not support symbolic links,
     this procedure returns `#f'.

 - procedure: file-type-direct filename
 - procedure: file-type-indirect filename
     If the file named FILENAME exists, `file-type-direct' returns a
     symbol specifying what type of file it is.  For example, if
     FILENAME refers to a directory, the symbol `directory' is
     returned.  If FILENAME doesn't refer to an existing file, `#f' is
     returned.

     If FILENAME refers to a symbolic link, `file-type-direct' returns
     the type of the link itself, while `file-type-indirect' returns
     the type of the file linked to.

     At this time, the symbols that can be returned are the following.
     The names are intended to be self-explanatory.  Most of these
     names can only be returned on particular operating systems, and so
     the operating-system name is prefixed to the name.

          regular
          directory
          unix-symbolic-link
          unix-character-device
          unix-block-device
          unix-named-pipe
          unix-socket
          os2-named-pipe
          win32-named-pipe

 - procedure: file-readable? filename
     Returns `#t' if FILENAME names a file that can be opened for
     input; i.e. a "readable" file.  Otherwise returns `#f'.

 - procedure: file-writeable? filename
     Returns `#t' if FILENAME names a file that can be opened for
     output; i.e. a "writeable" file.  Otherwise returns `#f'.

 - procedure: file-executable? filename
     Returns `#t' if FILENAME names a file that can be executed.
     Otherwise returns `#f'.  Under unix, an executable file is
     identified by its mode bits.  Under OS/2, an executable file has
     one of the file extensions `.exe', `.com', `.cmd', or `.bat'.
     Under Windows, an executable file has one of the file extensions
     `.exe', `.com', or `.bat'.

 - procedure: file-access filename mode
     MODE must be an exact integer between `0' and `7' inclusive; it is
     a bitwise-encoded predicate selector with `1' meaning
     "executable", `2' meaning "writeable", and `4' meaning "readable".
     `file-access' returns `#t' if FILENAME exists and satisfies the
     predicates selected by MODE.  For example, if MODE is `5', then
     FILENAME must be both readable and executable.  If FILENAME
     doesn't exist, or if it does not satisfy the selected predicates,
     `#f' is returned.

 - procedure: file-eq? filename1 filename2
     Determines whether FILENAME1 and FILENAME2 refer to the same file.
     Under unix, this is done by comparing the inodes and devices of
     the two files.  Under OS/2 and Windows, this is done by comparing
     the filename strings.

 - procedure: file-modes filename
     If FILENAME names an existing file, `file-modes' returns an exact
     non-negative integer encoding the file's permissions.  The
     encoding of this integer is operating-system dependent.  Under
     unix, it is the least-significant 12 bits of the `st_mode' element
     of the `struct stat' structure.  Under OS/2 and Windows, it is the
     file attribute bits, which are described below.  If FILENAME does
     not name an existing file, `#f' is returned.

 - procedure: set-file-modes! filename modes
     FILENAME must name an existing file.  MODES must be an exact
     non-negative integer that could have been returned by a call to
     `file-modes'.  `set-file-modes!' modifies the file's permissions
     to be those encoded by MODES.

 - variable: os2-file-mode/read-only
 - variable: os2-file-mode/hidden
 - variable: os2-file-mode/system
 - variable: os2-file-mode/directory
 - variable: os2-file-mode/archived
     The values of these variables are the "mode bits" that comprise the
     value returned by `file-modes' under OS/2.  These bits are small
     integers that are combined by adding to form a complete set of
     modes.  The integer zero represents a set of modes in which none
     of these bits are set.

 - variable: nt-file-mode/read-only
 - variable: nt-file-mode/hidden
 - variable: nt-file-mode/system
 - variable: nt-file-mode/directory
 - variable: nt-file-mode/archive
 - variable: nt-file-mode/normal
 - variable: nt-file-mode/temporary
 - variable: nt-file-mode/compressed
     The values of these variables are the "mode bits" that comprise the
     value returned by `file-modes' under Windows.  These bits are small
     integers that are combined by adding to form a complete set of
     modes.  The integer zero represents a set of modes in which none
     of these bits are set.

 - procedure: file-modification-time filename
     Returns the modification time of FILENAME as an exact non-negative
     integer.  The result may be compared to other file times using
     ordinary integer arithmetic.  If FILENAME names a file that does
     not exist, `file-modification-time' returns `#f'.

     In operating systems that support symbolic links, if FILENAME
     names a symbolic link, `file-modification-time' returns the
     modification time of the file linked to.  An alternate procedure,
     `file-modification-time-direct', returns the modification time of
     the link itself; in all other respects it is identical to
     `file-modification-time'.  For symmetry,
     `file-modification-time-indirect' is a synonym of
     `file-modification-time'.

 - procedure: file-access-time filename
     Returns the access time of FILENAME as an exact non-negative
     integer.  The result may be compared to other file times using
     ordinary integer arithmetic.  If FILENAME names a file that does
     not exist, `file-access-time' returns `#f'.

     In operating systems that support symbolic links, if FILENAME
     names a symbolic link, `file-access-time' returns the access time
     of the file linked to.  An alternate procedure,
     `file-access-time-direct', returns the access time of the link
     itself; in all other respects it is identical to
     `file-access-time'.  For symmetry, `file-access-time-indirect' is
     a synonym of `file-access-time'.

 - procedure: set-file-times! filename access-time modification-time
     FILENAME must name an existing file, while ACCESS-TIME and
     MODIFICATION-TIME must be valid file times that might have been
     returned by `file-access-time' and `file-modification-time',
     respectively.  `set-file-times!' alters the access and modification
     times of the file specified by FILENAME to the values given by
     ACCESS-TIME and MODIFICATION-TIME, respectively.  For convenience,
     either of the time arguments may be specified as `#f'; in this
     case the corresponding time is not changed.  `set-file-times!'
     returns an unspecified value.

 - procedure: current-file-time
     Returns the current time as an exact non-negative integer, in the
     same format used by the above file-time procedures.  This number
     can be compared to other file times using ordinary arithmetic
     operations.

 - procedure: file-touch filename
     "Touches" the file named FILENAME.  If the file already exists,
     its modification time is set to the current file time and `#f' is
     returned.  Otherwise, the file is created and `#t' is returned.
     This is an atomic test-and-set operation, so it is useful as a
     synchronization mechanism.

 - procedure: file-length filename
     Returns the length, in bytes, of the file named FILENAME as an
     exact non-negative integer.

 - procedure: file-attributes filename
     This procedure determines if the file named FILENAME exists, and
     returns information about it if so; if the file does not exist, it
     returns `#f'.

     In operating systems that support symbolic links, if FILENAME
     names a symbolic link, `file-attributes' returns the attributes of
     the link itself.  An alternate procedure,
     `file-attributes-indirect', returns the attributes of the file
     linked to; in all other respects it is identical to
     `file-attributes'.  For symmetry, `file-attributes-direct' is a
     synonym of `file-attributes'.

   The information returned by `file-attributes' is decoded by accessor
procedures.  The following accessors are defined in all operating
systems:

 - procedure: file-attributes/type attributes
     The file type: `#t' if the file is a directory, a character string
     (the name linked to) if a symbolic link, or `#f' for all other
     types of file.

 - procedure: file-attributes/access-time attributes
     The last access time of the file, an exact non-negative integer.

 - procedure: file-attributes/modification-time attributes
     The last modification time of the file, an exact non-negative
     integer.

 - procedure: file-attributes/change-time attributes
     The last change time of the file, an exact non-negative integer.

 - procedure: file-attributes/length attributes
     The length of the file in bytes.

 - procedure: file-attributes/mode-string attributes
     The mode string of the file, a newly allocated string showing the
     file's mode bits.  Under unix, this string is in unix format.
     Under OS/2 and Windows, this string shows the standard "DOS"
     attributes in their usual format.

 - procedure: file-attributes/n-links attributes
     The number of links to the file, an exact positive integer.  Under
     Windows and OS/2, this is always `1'.

   The following additional accessors are defined under unix:

 - procedure: file-attributes/uid attributes
     The user id of the file's owner, an exact non-negative integer.

 - procedure: file-attributes/gid attributes
     The group id of the file's group, an exact non-negative integer.

 - procedure: file-attributes/inode-number attributes
     The inode number of the file, an exact non-negative integer.

   The following additional accessor is defined under OS/2 and Windows:

 - procedure: file-attributes/modes attributes
     The attribute bits of the file.  This is an exact non-negative
     integer containing the file's attribute bits, exactly as specified
     by the operating system's API.

   The following additional accessor is defined under OS/2:

 - procedure: file-attributes/allocated-length attributes
     The allocated length of the file, which can be larger than the
     length of the file due to fixed-length allocation units.

Directory Reader
================

 - procedure: directory-read directory [sort?]
     DIRECTORY must be an object that can be converted into a pathname
     by
     `->pathname'.  The directory specified by DIRECTORY is read, and
     the contents of the directory is returned as a newly allocated
     list of absolute pathnames.  The result is sorted according to the
     usual sorting conventions for directories, unless SORT? is
     specified as `#f'.  If DIRECTORY has name, type, or version
     components, the returned list contains only those pathnames whose
     name, type, and version components match those of DIRECTORY;
     `wild' or `#f' as one of these components means "match anything".

     The OS/2 and Windows implementations support "globbing", in which
     the characters `*' and `?' are interpreted to mean "match
     anything" and "match any character", respectively.  This "globbing"
     is supported only in the file part of DIRECTORY.

Date and Time
=============

   MIT Scheme provides a simple set of procedures for manipulating date
and time information.  There are four time representations, each of
which serves a different purpose.  Each representation may be converted
to any of the others.

   The primary time representation, "universal time", is an exact
non-negative integer counting the number of seconds that have elapsed
since midnight January 1, 1900 UTC.  (UTC stands for "Coordinated
Universal Time", and is the modern name for Greenwich Mean Time.)  This
format is produced by `get-universal-time' and
`decoded-time->universal-time'.

   The second representation, "decoded time", is a record structure in
which the time is broken down into components, such as month, minute,
etc.  Decoded time is always relative to a particular time zone, which
is a component of the structure.  This format is produced by
`global-decoded-time' and `local-decoded-time'.

   The third representation, "file time", is an exact non-negative
integer that is larger for increasing time.  Unlike universal time,
this representation is operating-system dependent.  This format is
produced by all of the file-attribute procedures, for example
`file-modification-time' and `file-attributes'.

   The fourth representation, the "time string", is an external
representation for time.  This format is defined by RFC-822, `Standard
for the format of ARPA Internet text messages', with the modification
that years are represented as four-digit numbers rather than two-digit
numbers.  This format is the standard format for Internet email and
numerous other network protocols.

   Within this section, argument variables named UNIVERSAL-TIME,
DECODED-TIME, FILE-TIME, and TIME-STRING are respectively required to
be of the corresponding format.

Universal Time
--------------

 - procedure: get-universal-time
     Return the current time in universal format.

          (get-universal-time) => 3131453078

 - variable: epoch
     `epoch' is the representation of midnight January 1, 1970 UTC in
     universal-time format.

          epoch => 2208988800

Decoded Time
------------

   Objects representing standard time components, such as seconds and
minutes, are required to be exact non-negative integers.  Seconds and
minutes must be inclusively between `0' and `59'; hours between `0' and
`23'; days between `1' and `31'; months between `1' and `12'; years are
represented in "four-digit" form, in which 1999 is represented as
`1999' -- _not_ `99'.

 - procedure: local-decoded-time
     Return the current time in decoded format.  The decoded time is
     represented in the local time zone.

          (pp (local-decoded-time))
          -| #[decoded-time 76]
          -| (second 2)
          -| (minute 12)
          -| (hour 11)
          -| (day 27)
          -| (month 4)
          -| (year 1999)
          -| (day-of-week 1)
          -| (daylight-savings-time 1)
          -| (zone 5)

 - procedure: global-decoded-time
     Return the current time in decoded format.  The decoded time is
     represented in UTC.

          (pp (global-decoded-time))
          -| #[decoded-time 77]
          -| (second 8)
          -| (minute 12)
          -| (hour 15)
          -| (day 27)
          -| (month 4)
          -| (year 1999)
          -| (day-of-week 1)
          -| (daylight-savings-time 0)
          -| (zone 0)

 - procedure: make-decoded-time second minute hour day month year [zone]
     Return a new decoded-time object representing the given time.  The
     arguments must be valid components according to the above rules,
     and must form a valid date.

     If ZONE is not supplied or is `#f', the resulting decoded time
     will be represented in the local time zone.  Otherwise, ZONE must
     be a valid time zone, and the result will be represented in that
     zone.

     *Warning*: because this procedure depends on the operating
     system's runtime library, it is not capable of representing all
     dates.  In particular, on most unix systems, it is not possible to
     encode dates that occur prior to midnight, January 1, 1970 UTC.
     Attempting to do this will signal an error.

          (pp (make-decoded-time 0 9 11 26 3 1999))
          -| #[decoded-time 19]
          -| (second 0)
          -| (minute 9)
          -| (hour 11)
          -| (day 26)
          -| (month 3)
          -| (year 1999)
          -| (day-of-week 4)
          -| (daylight-savings-time 0)
          -| (zone 5)

          (pp (make-decoded-time 0 9 11 26 3 1999 3))
          -| #[decoded-time 80]
          -| (second 0)
          -| (minute 9)
          -| (hour 11)
          -| (day 26)
          -| (month 3)
          -| (year 1999)
          -| (day-of-week 4)
          -| (daylight-savings-time 0)
          -| (zone 3)

 - procedure: decoded-time/second decoded-time
 - procedure: decoded-time/minute decoded-time
 - procedure: decoded-time/hour decoded-time
 - procedure: decoded-time/day decoded-time
 - procedure: decoded-time/month decoded-time
 - procedure: decoded-time/year decoded-time
     Return the corresponding component of DECODED-TIME.

          (decoded-time/second (local-decoded-time)) => 17
          (decoded-time/year (local-decoded-time)) => 1999
          (decoded-time/day (local-decoded-time)) => 26

 - procedure: decoded-time/day-of-week decoded-time
     Return the day of the week on which DECODED-TIME falls, encoded as
     an exact integer between `0' (Monday) and `6' (Sunday), inclusive.

          (decoded-time/day-of-week (local-decoded-time)) => 4

 - procedure: decoded-time/daylight-savings-time? decoded-time
     Return `#t' if DECODED-TIME is represented using daylight savings
     time.  Otherwise return `#f'.

          (decoded-time/daylight-savings-time? (local-decoded-time))
                            => #f

 - procedure: decoded-time/zone decoded-time
     Return the time zone in which DECODED-TIME is represented.  This
     is an exact rational number between `-24' and `+24' inclusive,
     that when multiplied by `3600' is an integer.  The value is the
     number of hours west of UTC.

          (decoded-time/zone (local-decoded-time)) => 5

 - procedure: time-zone? object
     Returns `#t' if OBJECT is an exact number between `-24' and `+24'
     inclusive, that when multiplied by `3600' is an integer.

          (time-zone? -5)   => #t
          (time-zone? 11/2) => #t
          (time-zone? 11/7) => #f

 - procedure: month/max-days month
     Returns the maximum number of days possible in MONTH.  MONTH must
     be an exact integer between `1' and `12' inclusive.

          (month/max-days 2) => 29
          (month/max-days 3) => 31
          (month/max-days 4) => 30

File Time
---------

   As stated above, file time is operating-system dependent.  As of this
writing, two formats are used.  For unix and Windows systems, file time
is the number of seconds since midnight January 1, 1970 UTC (the
standard unix time convention).

   OS/2 represents file time as a 32-bit unsigned integer, in which the
time components are broken down into unsigned bit fields.  The
components are always stated in local time.  The fields, from MSB to
LSB, are:

   * 7 bits representing the year, relative to 1900.

   * 4 bits representing the month, numbered 1 to 12.

   * 5 bits representing the day of the month, numbered 1 to 31.

   * 5 bits representing the hour of the day, numbered 0 to 23.

   * 6 bits representing the minute, numbered 0 to 59.

   * 5 bits representing the second.  This field is unusual in that it
     counts units of two seconds, so it is a number between 0 and 29,
     representing second counts corresponding to 0 through 58.

   The following procedures generate their results in file-time format:

     file-access-time
     file-access-time-direct
     file-access-time-indirect
     file-modification-time
     file-modification-time-direct
     file-modification-time-indirect
     file-attributes/access-time
     file-attributes/modification-time
     file-attributes/change-time

Additionally, `set-file-times!' accepts its time arguments in file-time
format.

Time-Format Conversion
----------------------

   The procedures described in this section convert times from one
format to another.

 - procedure: universal-time->local-decoded-time universal-time
 - procedure: universal-time->global-decoded-time universal-time
     Converts an argument in universal-time format to decoded-time
     format.  The result is in the local time zone or UTC, respectively.

          (pp (universal-time->local-decoded-time (get-universal-time)))
          -| #[decoded-time 21]
          -| (second 23)
          -| (minute 57)
          -| (hour 17)
          -| (day 29)
          -| (month 4)
          -| (year 1999)
          -| (day-of-week 3)
          -| (daylight-savings-time 1)
          -| (zone 5)

          (pp (universal-time->global-decoded-time
               (get-universal-time)))
          -| #[decoded-time 22]
          -| (second 27)
          -| (minute 57)
          -| (hour 21)
          -| (day 29)
          -| (month 4)
          -| (year 1999)
          -| (day-of-week 3)
          -| (daylight-savings-time 0)
          -| (zone 0)

 - procedure: universal-time->file-time universal-time
     Converts an argument in universal-time format to file-time format.

          (universal-time->file-time (get-universal-time))
              => 925422988

 - procedure: universal-time->local-time-string universal-time
 - procedure: universal-time->global-time-string universal-time
     Converts an argument in universal-time format to a time string.
     The result is in the local time zone or UTC, respectively.

          (universal-time->local-time-string (get-universal-time))
              => "Thu, 29 Apr 1999 17:55:31 -0400"
          (universal-time->global-time-string (get-universal-time))
              => "Thu, 29 Apr 1999 21:55:51 +0000"

 - procedure: decoded-time->universal-time decoded-time
     Converts an argument in decoded-time format to universal-time
     format.

          (decoded-time->universal-time (local-decoded-time))
              => 3134411942
          (decoded-time->universal-time (global-decoded-time))
              => 3134411947

 - procedure: decoded-time->file-time decoded-time
     Converts an argument in decoded-time format to file-time format.

          (decoded-time->file-time (local-decoded-time))
              => 925423191
          (decoded-time->file-time (global-decoded-time))
              => 925423195

 - procedure: decoded-time->string decoded-time
     Convert an argument in decoded-time format to a time string.

          (decoded-time->string (local-decoded-time))
              => "Thu, 29 Apr 1999 18:00:43 -0400"
          (decoded-time->string (global-decoded-time))
              => "Thu, 29 Apr 1999 22:00:46 +0000"

 - procedure: file-time->universal-time file-time
     Converts an argument in universal-time format to file-time format.

          (file-time->universal-time (file-modification-time "/"))
              => 3133891907

 - procedure: file-time->local-decoded-time file-time
 - procedure: file-time->global-decoded-time file-time
     Converts an argument in file-time format to decoded-time format.
     The result is in the local time zone or UTC, respectively.

          (pp (file-time->local-decoded-time
               (file-modification-time "/")))
          -| #[decoded-time 26]
          -| (second 47)
          -| (minute 31)
          -| (hour 17)
          -| (day 23)
          -| (month 4)
          -| (year 1999)
          -| (day-of-week 4)
          -| (daylight-savings-time 1)
          -| (zone 5)

          (pp (file-time->global-decoded-time
               (file-modification-time "/")))
          -| #[decoded-time 27]
          -| (second 47)
          -| (minute 31)
          -| (hour 21)
          -| (day 23)
          -| (month 4)
          -| (year 1999)
          -| (day-of-week 4)
          -| (daylight-savings-time 0)
          -| (zone 0)

 - procedure: file-time->local-time-string file-time
 - procedure: file-time->global-time-string file-time
     Converts an argument in file-time format to a time string.  The
     result is in the local time zone or UTC, respectively.

          (file-time->local-time-string (file-modification-time "/"))
              => "Fri, 23 Apr 1999 17:31:47 -0400"
          (file-time->global-time-string (file-modification-time "/"))
              => "Fri, 23 Apr 1999 21:31:47 +0000"

 - procedure: string->universal-time time-string
     Converts a time-string argument to universal-time format.

          (string->universal-time "Fri, 23 Apr 1999 21:31:47 +0000")
              => 3133888307
          (string->universal-time "Fri, 23 Apr 1999 17:31:47 -0400")
              => 3133888307

 - procedure: string->decoded-time time-string
     Converts a time-string argument to decoded-time format.

          (pp (string->decoded-time "Fri, 23 Apr 1999 17:31:47 -0400"))
          -| #[decoded-time 30]
          -| (second 47)
          -| (minute 31)
          -| (hour 17)
          -| (day 23)
          -| (month 4)
          -| (year 1999)
          -| (day-of-week 4)
          -| (daylight-savings-time 0)
          -| (zone 4)

 - procedure: string->file-time time-string
     Converts a time-string argument to file-time format.

          (string->file-time "Fri, 23 Apr 1999 17:31:47 -0400")
              => 924899507