File system access
==================

These procedures operate on the file system via the facilities defined by POSIX and offer more than standard & portable R5RS operations.  All of these names are exported by the structures posix-files and posix.

 -- procedure: open-directory-stream filename returns dir-stream
 -- procedure: directory-stream? object returns boolean
 -- procedure: read-directory-stream dir-stream returns filename or #f
 -- procedure: close-directory-stream dir-stream returns unspecified
     Directory streams are the low-level interface provided by POSIX to enumerate the contents of a directory.  Open-directory-stream opens a new directory stream that will enumerate all of the files within the directory named by FILENAME.  Directory-stream? is the disjoint type predicate for directory streams. Read-directory-stream consumes the next filename from DIR-STREAM and returns it, or returns #f if the stream has finished.  Note that read-directory-stream will return only simple filenames, not full pathnames.  Close-directory-stream closes DIR-STREAM, removing any storage it required in the operating system.  Closing an already closed directory stream has no effect.

 -- procedure: list-directory filename returns string list
     Returns the list of filenames in the directory named by FILENAME. This is equivalent to opening a directory stream, repeatedly reading from it & accumulating the list of filenames, and closing the stream.

 -- procedure: working-directory returns string
 -- procedure: set-working-directory! string returns unspecified
     These access the working directory's filename of the current process.

 -- procedure: open-file pathname file-options [file-mode] returns port
     Opens a port to the file named by the string PATHNAME. FILE-OPTIONS specifies various aspects of the port.  The optional FILE-MODE argument is used only if the file to be opened does not already exist; it specifies the permissions to be assigned to the file if it is created.  The returned port is an input port if the given options include read-only; otherwise open-file returns an output port.  Because Scheme48 does not support combined input/output ports, dup-switching-mode can be used to open an input port for output ports opened with the read-write option.

File options are stored in a boxed mask representation.  File option sets are created with file-options and tested with file-options-on?.

 -- syntax: file-options name ... returns file-options
 -- procedure: file-options-on? optionsa optionsb returns boolean
     File-options evaluates to a file option set, suitable for passing to open-file, that includes all of the given named options. File-options-on? returns true if OPTIONSA includes all of the options in OPTIONSB, or false if otherwise.

     The following file option names are supported as arguments to the file-options syntax:

     create
          create file if it does not already exist; a FILE-MODE argument is required to be passed to open-file if the create option is specified

     exclusive
          an error will be signalled if this option & create are both set and the file already exists

     no-controlling-tty
          if the pathname being opened is a terminal device, the terminal will not become the controlling terminal of the process

     truncate
          file is truncated

     append
          written data to the newly opened file will be appended to the existing contents

     nonblocking
          read & write operations will not block

     read-only
          file may not be written to, only read from

     read-write
          file may be both read from & written to

     write-only
          file may not be read from, only written to

     The last three are all mutually exclusive.

Examples:

     (open-file "some-file.txt"
                (file-options create write-only)
                (file-mode read owner-write)) lisp

     returns an output port that writes to a newly-created file that can be
     read from by anyone but written to only by the owner.  Once the file
     some-file.txt exists,

          (open-file "some-file.txt"
                     (file-options append write-only)) lisp

          will open an output port that appends to the file.

          POSIX I/O utilities,I/o-flags & set-i/o-flags!
          can be used to access the append, nonblocking, and
          read/write file options of ports, as well as modify the append &
          nonblocking options.

          To keep port operations from blocking in the Scheme48 process, output
          ports are set to be nonblocking at the time of creation.  (Input ports
          are managed using select(2).)  Set-i/o-flags! can be used
          to make an output port blocking, for example directly before forking,
          but care should be exercised, because the Scheme48 run-time system may
          be confused if an I/O operation blocks.

           -- procedure: set-file-creation-mask! file-mode returns file-mode
               Sets the file creation mask to be FILE-MODE.  Bits set in
               FILE-MODE are cleared in the modes of any files or directories
               subsequently created by the current process.

           -- procedure: link existing-pathname new-pathname returns unspecified
           -- procedure: make-directory pathname file-mode returns unspecified
           -- procedure: make-fifo pathname file-mode returns unspecified
               Link creates a hard link for the file at EXISTING-PATHNAME
               at NEW-PATHNAME.  Make-directory creates a new directory
               at the locations specified by PATHNAME with the the file mode
               FILE-MODE.  Make-fifo does similarly, but it creates a
               FIFO (first-in first-out) file instead of a directory.

           -- procedure: unlink pathname returns unspecified
           -- procedure: remove-directory pathname returns unspecified
           -- procedure: rename old-pathname new-pathname returns unspecified
               Unlink removes a link at the location PATHNAME.
               Remove-directory removes a directory at the location specified
               by PATHNAME.  The directory must be empty; an exception is
               signalled if it is not.  Rename moves the file at the location
               OLD-PATHNAME to the new location NEW-PATHNAME.

           -- procedure: accessible? pathname access-mode more-modes ... returns boolean
           -- syntax: access-mode name returns access mode
               Accessible? returns true if PATHNAME is accessible by all
               of the given access modes.  (There must be at least one access mode
               argument.)  Access-mode evaluates to an access mode, suitable for
               passing to accessible?, from the given name.  The allowed names
               are read, write, execute, & exists.

          Information about files can be queried using the file info
          abstraction.  Every file has a corresponding file info record, which
          contains various data about the file including its name, its type,
          its device & inode numbers, the number of links to it, its size in
          bytes, its owner, its group, its file mode, and its access times.

           -- procedure: get-file-info pathname returns file-info
           -- procedure: get-file/link-info pathname returns file-info
           -- procedure: get-port-info fd-port returns file-info
               Get-file-info & get-file/link-info return a file info
               record for the files named by PATHNAME.  Get-file-info
               follows symbolic links, however, while get-file/link info does
               not.  Get-port-info returns a file info record for the file that
               FD-PORT is a port atop a file descriptor for.  If FD-PORT
               does not read from or write to a file descriptor, an error is
               signalled.

           -- procedure: file-info? object returns boolean
           -- procedure: file-info-name file-info returns string
           -- procedure: file-info-device file-info returns integer
           -- procedure: file-info-inode file-info returns integer
           -- procedure: file-info-link-count file-info returns integer
           -- procedure: file-info-size file-info returns integer
           -- procedure: file-info-owner file-info returns user-id
           -- procedure: file-info-group file-info returns group-id
           -- procedure: file-info-mode file-info returns file-mode
           -- procedure: file-info-last-access file-info returns time
           -- procedure: file-info-last-modification file-info returns time
           -- procedure: file-info-last-change file-info returns time
               Accessors for various file info record fields.  The name is the string
               passed to get-file-info or get-file/link-info, if the
               file info record was created with either of those two, or the name of
               the file that the file descriptor of the port queried was created on,
               if the file info record was obtained with get-port-info.

           -- procedure: file-info-type file-info returns file-type
           -- syntax: file-type name returns file-type
           -- procedure: file-type? object returns boolean
           -- procedure: file-type-name file-type returns symbol
               File-info-type returns the type of the file as a file type
               object.  File types may be compared using eq?.  File-type
               evaluates to a file type of the given name.  The disjoint type predicate
               for file types is file-type?.  File-type-name returns the
               symbolic name that represents FILE-TYPE.

               The valid file type names are:

                 regular

                 directory

                 character-device

                 block-device

                 fifo

                 symbolic-link (not required by POSIX)

                 socket (not required by POSIX)

                 other

          File modes are boxed integers that represent POSIX file
          protection masks.

           -- syntax: file-mode permission-name ... returns file-mode
           -- procedure: file-mode? object returns boolean
               File-mode evaluates to a file mode object that contains all of
               the specified permissions.  File-mode? is the disjoint type
               predicate for file mode descriptor objects.  These are all of the names,
               with their corresponding octal bit masks and meanings, allowed to be
               passed to file-mode:

               Permission name   Octal mask   Description
               set-uid       #o4000   set user id when executing
               set-gid       #o2000   set group id when executing
               owner-read    #o0400   read by owner
               owner-write   #o0200   write by owner
               owner-exec    #o0100   execute (or search) by owner
               group-read    #o0040   read by group
               group-write   #o0020   write by group
               group-exec    #o0010   execute (or search) by group
               other-read    #o0004   read by others
               other-write   #o0002   write by others
               other-exec    #o0001   execute (or search) by others

               Also, several compound masks are supported for convenience:

               Permission set name   Octal mask   Description
               owner   #o0700   read, write, & execute by owner
               group   #o0070   read, write, & execute by group
               other   #o0007   read, write, & execute by others
               read    #o0444   read by anyone
               write   #o0111   write by anyone
               exec    #o0777   read, write, & execute by anyone

           -- procedure: file-mode+ file-mode ... returns file-mode
           -- procedure: file-mode- file-modea file-modeb returns file-mode
           -- procedure: file-mode=? file-modea file-modeb returns boolean
           -- procedure: file-mode<=? file-modea file-modeb returns boolean
           -- procedure: file-mode>=? file-modea file-modeb returns boolean
               File-mode+ returns a file mode that contains all of the
               permissions specified in any of its arguments.  File-mode-
               returns a file mode that contains all of FILE-MODEA's
               permissions not in FILE-MODEB.  File-mode=? tests
               whether two file modes are the same.  File-mode<=? returns true
               if each successive file mode argument has the same or more permissions
               as the previous one.  File-mode>=? returns true if each
               successive file mode argument has the same or fewer permissions as the
               previous one.

           -- procedure: file-mode->integer file-mode returns integer
           -- procedure: integer->file-mode integer returns file-mode
               These convert between file mode objects and Unix file mode masks as
               integers.  The integer representations may or may not be the masks used
               by the underlying operating system.