The Standard ML Basis Library


The OS.FileSys structure

The OS.FileSys structure provides facilities for accessing and operating on the file system. They are meant to be portable across operating systems. They raise OS.SysErr with an argument in case of errors.

Except for fullPath and realPath, functions taking a string argument will raise the OS.SysErr exception of the string is empty.

It is expected that all functions taking a pathname as an argument (e.g., modTime or OS.Process.system) will resolve any components corresponding to symbolic links. The obvious exceptions to this rule are <isLink and readLink, where only symbolic links appearing as directory components of the pathname are resolved.

We need a general discussion of dirstreams, working directory, directory structure, etc. The introduction should say something about the model of a file system that these functions use; what features they support and what examples of features that require an OS-specific library. We should also note that the particular semantics, especially concerning errors, is OS dependent.


Synopsis

signature OS_FILE_SYS
structure FileSys : OS_FILE_SYS

Interface

type dirstream
val openDir : string -> dirstream
val readDir : dirstream -> string
val rewindDir : dirstream -> unit
val closeDir : dirstream -> unit
val chDir : string -> unit
val getDir : unit -> string
val mkDir : string -> unit
val rmDir : string -> unit
val isDir : string -> bool
val isLink : string -> bool
val readLink : string -> string
val fullPath : string -> string
val realPath : string -> string
val modTime : string -> Time.time
val fileSize : string -> Position.int
val setTime : (string * Time.time option) -> unit
val remove : string -> unit
val rename : {old : string, new : string} -> unit
datatype access_mode
  = A_READ
  | A_WRITE
  | A_EXEC
val access : (string * access_mode list) -> bool
val tmpName : unit -> string
eqtype file_id
val fileId : string -> file_id
val hash : file_id -> word
val compare : (file_id * file_id) -> order

Description

type dirstream

openDir s
opens directory s and creates a directory stream for use with readDir, rewindDir and closeDir. The stream reads the directory entries off the file system in some unspecified order. Raises OS.SysErr if, for example, the directory does not exist or is not accessible.

readDir dir
returns and removes one file name from the directory stream dir. When the directory stream is empty (that is, when all entries have been read from the stream), the empty string "" is returned. readDir filters out the names corresponding to the current and parent arcs.

rewindDir dir
resets the directory stream dir, as if it had just been opened. Raises OS.SysErr if, for example, the directory does not exist or is not accessible.

closeDir dir
closes the directory stream dir, releasing any system resources associated with it. Any subsequent operations on the stream will raise exception OS.SysErr. However, closing a closed directory stream has no effect.

chDir s
changes the current working directory to s. This affects future calls to all functions that access the file system. These include the input/output functions such as TextIO.openIn and TextIO.openOut, and functions defined in this structure. Raises OS.SysErr if, for example, the directory does not exist or is not readable.

The chDir function will also change the current volume (on systems with volumes) if one is specified. chDir will not allow the user to change the current working directory of another volume than the current, even on systems where this concept is otherwise supported.

getDir ()
returns an absolute canonical pathname of the current working directory. This includes the current volume for systems supporting volumes.

mkDir s
creates directory s on the file system. Raises OS.SysErr if, for example, the directory in which s is to be created does not exist or is not writable.

rmDir s
removes directory s from the file system. Raises OS.SysErr if, for example, s does not exist or if the directory in which s resides is not writable, or if the directory is not empty.

isDir s
tests whether s is a directory. Raises OS.SysErr if, for example, s does not exist or if the directory in which s resides is not accessible.

isLink s
returns true if s names a symbolic link. Raises OS.SysErr if, for example, s does not exist or there is an access violation. On operating systems without symbolic links, it will always return false unless an exception is raised.

readLink s
returns the contents of the symbolic link s. Raises OS.SysErr if, for example, s does not exist or is not a symbolic link, or there is an access violation. On operating systems without symbolic links, it raises OS.SysErr unconditionally.

The precise form of the returned string, in particular, whether it corresponds to an absolute or relative path, is system-dependent.

fullPath s
returns an absolute canonical path that names the same file-system object as s. The resulting path will have a volume prefix (on systems supporting volumes), all occurrences of the current, parent, and empty arcs will have been expanded or removed, and any symbolic links will have been fully expanded. An empty s is treated as ".". It raises OS.SysErr if, for example, a directory on the path, or the file or directory named, does not exist or is not accessible or if there is a link loop.

realPath s
returns a canonical path that names the same file-system object as s. If s is an absolute path, then realPath acts like fullPath. If s is relative and on the same volume as the current working directory, then it returns a path that is relative to the current working directory. Otherwise, it raises OS.Path.Path.
Implementation note:

realPath can be implemented as:

fun realPath p = if OS.Path.isAbsolute p
      then fullPath p
      else OS.Path.mkRelative (fullPath p, fullPath (getDir ()))
	  


modTime s
returns the modification time of file s. Raises OS.SysErr if, for example, s does not exist or if the directory in which s resides is not accessible.

fileSize s
returns the size of file s in bytes. Raises OS.SysErr if, for example, s does not exist or if the directory in which s resides is not accessible.

setTime (s, opt)
sets the modification and access time of file s. If opt is SOME t, then the time t is used; otherwise the current time, that is, Time.now(), is used. Raises OS.SysErr if, for example, s does not exist or if the directory in which s resides is not accessible or the user does not have appropriate permission.

remove s
deletes file s from the file system. Raises OS.SysErr if, for example, s does not exist or is not writable, or if the directory in which s resides is not writable.

If one removes a file that has been opened for reading or writing, the behavior of subsequent reads and writes is undefined. For example, removing the file may close all existing streams or generate an exception. The Unix idiom of opening a file and then removing it is not portable.

rename {old, new}
changes the name of file old to new. If new and old refer to the same file, rename does nothing. If a file called new exists, it is removed. Raises OS.SysErr if, for example, old does not exist, or if one of the directories in which old or new reside is not writable. This may also fail if old refers to an open file, or if old and new are on different file systems, i.e., if a copy is required.

datatype access_mode

access (s, accs)
tests the access permissions of file s, expanding symbolic links as necessary. If the list accs of required access permission is empty, it tests whether s exists. If accs contains A_READ, A_WRITE or A_EXEC, respectively, it tests whether the user process has read, write or execute permission for the file, testing their conjunction if more than one are present. Note that access is also implicitly testing the user's access to the parent directories of the file. The function will only raise OS.SysErr for errors unrelated to resolving the pathname and the related permissions, such as being interrupted by a signal during the system call.

tmpName ()
returns a valid file name s that is not the name of a currently existing file, and is suitable for naming a temporary file. This will raise SysErr if it can detect that it cannot create a unique file name. Even if it succeeds, there is no guarantee that a file of that name was not created shortly after the call to tmpName, although this situation is unlikely.

eqtype file_id
a unique identifier associated with a file system object. Not persistent across changes in file system (e.g., mount/unmount) but is better than path names for uniquely identifying files.

fileId s
returns the unique file_id value associated with the file system object designated by the pathname s. In particular, if fileId p = fileId p', then the paths p and p' refer to the same file system object.

hash fid
returns a hashvalue associated with fid.
Implementation note:

hash must have the property that values produced are well distributed when taken modulo 2(n) for any n.



compare (fid, fid')
returns LESS, EQUAL or GREATER when fid is less than, equal to, or greater than fid', respectively, in some underlying linear ordering on file_id values.


See Also

OS, OS.Path, TextIO, BinIO

[ INDEX | TOP | Parent | Root ]

Last Modified October 6, 1997
Comments to John Reppy.
Copyright © 1997 Bell Labs, Lucent Technologies