A file is something that the Read and Write procedures can work on. One way of categorizing files is by whether they provide storage. Regular files provide storage (with a lifetime and addressibility independent of the execution of a single process).
Device files provide an input/output interface to peripheral devices.
There are two subclasses of device files: unstructured and structured.
Unstructured devices allow stream-like transfers; some of them may be
manipulated in idiosyncratic ways via the IOCtl procedure (see page
). Structured devices provide block-level access to storage
devices such as disks and tapes. (No structured devices currently exist
in the Taos implementation of OS.)
Pipes and the more general sockets provide an alternative to RPC for stream-style interprocess communication. Pipes only allow communication between processes with a common ancestor, and therefore within the same machine. Sockets allow communication between arbitrary processes on arbitrary machines interconnected by any of several internetwork protocols. (Sockets are not currently available via OS, nor are they present in the kernel-call interface to Taos.)
Taos note: Appendix D.10, page , describes
the available devices.
Associated with each regular or device file is a set of attributes
intended to help manage the file. These attributes include the user name
of the owner of the file, the access group of the file, and timestamps
recording file usage. The full set of attributes is enumerated in Section
4.6, page .
An open-file object represents the ability to perform a specific set of
operations on a specific file. It also maintains temporary state
associated with access to that file, namely flags governing transfer
direction and related matters, a file pointer recording a position (for a
regular file), and an advisory lock (for regular files and for device
files). Open-file objects are created by the procedures Open, OpenRead,
OpenWrite, OpenSearch, and OpenPipe (see Section 4.2, page
).
A file is marked for deletion when the last name for it is removed from
the name space (see the Remove procedure, page ), but
the actual deletion is postponed as long as one or more open-file objects
referring to the file continue to exist.
A client of OS uses a file handle (a value of type File) to refer to an
open-file object. File handles are returned by the procedures that create
new open-file objects. They are also returned by Dup and GetDescriptor,
which return file handles referring to existing open-file objects. A
process should call Close (see page ) when it is
finished with a file handle. Close breaks a file handle's reference to
the open-file object; it is called automatically when there are no more
references to a file handle (via the Modula-2+ object cleanup mechanism).
Also, when a process terminates, all file handles it holds are closed.
An open-file object continues to exist as long as there are one or more file handles referring to it; when the last such file handle is closed, the open-file object ceases to exist.
Each process has an array of file handles that were supplied to it when it
was started (see the SetDescriptor procedure on page ).
Elements of the array are obtained via the GetDescriptor procedure (see
page
). The array itself is read-only, though any
of the procedures provided in OS, including Close, can be applied to the
file handles returned by GetDescriptor.