include "sys.m"; sys := load Sys Sys->PATH;
When a process presents a file name to Inferno, it is evaluated by the following algorithm.
The collection of files reachable from the root is called the name space of a process.
A program can use bind or mount (see sys-bind(2)) to say that whenever a specified file is reached during an evaluation, that evaluation continues instead from a second specified file. Also, these same calls create union directories, which are concatenations of ordinary directories that are searched sequentially until the desired element is found. Using bind and mount to do name space adjustment affects only the current name space group (see below, and sys-pctl(2)). Certain conventions about the layout of the name space should be preserved; see namespace(4).
The operating system kernel records the file name used to access each open file or directory. If the file is opened by a relative path name (one that does not begin / or #), the system makes the stored name absolute by prefixing the string associated with the current directory. Similar lexical adjustments are made for path names containing . (dot) or .. (dot-dot). By this process, the system maintains a record of the route by which each file was accessed. Although there is a possibility for error—the name is not maintained after the file is opened, so removals and renamings can confound it—this simple method usually permits the system to return, via sys-fd2path(2) and related calls such as those of workdir(2), a valid name that may be used to find a file again. This is also the source of the names reported in the name space listing of ns(1) or the ns file of prog(3).
Inferno gives special meaning in path names only to `/' and an initial `#', but individual file servers might impose further restrictions or conventions of their own. For instance, the set of characters allowed in names by fs(3) ultimately depends on the host operating system; and dial(2) and cs(8) amongst others use `!' as a delimiter in network names, preventing their use in the names of network devices.
Integer file descriptor values range from 0 to n in the current system, where the upper bound depends on the underlying operating system. The system allocates the numbers by selecting the lowest unused descriptor. They may be reassigned using dup (see sys-dup(2)). Integer file descriptor values are indices into a kernel-resident file descriptor table, which is inherited from the parent when a process is created by a Limbo spawn operation. A set of processes, called a file descriptor group, shares that table, so files opened by one process may be read and written by other processes in the group. See sys-pctl(2) for more information.
By convention, file descriptor 0 is the standard input, 1 is the standard output, and 2 is the standard error output. The operating system is unaware of these conventions; it is permissible to close file 0, or even to replace it by a file open only for writing, but many programs will be confused by such chicanery.
Files are normally read or written in sequential order. The I/O position in the file is called the file offset and may be set arbitrarily using the seek system call (sys-seek(2)). An offset can also be passed as a parameter to pread and pwrite (see sys-read (2)).
Inferno provides no guarantee of consistency should several processes access a file concurrently. Guaranteed synchronous writes are not available. Whether the exclusive-use attributes described in sys-open(2) and sys-stat(2) will be honoured for a file depends entirely on the underlying file server (eg, fs(3)). Record locking in the underlying file system is not supported by Inferno. Processes can coordinate their file operations by other mechanisms.
Atomicity is guaranteed for byte counts smaller than the Styx message size; see read(5).
Directories may be opened and read much like regular files (see sys-dirread(2)). They contain an integral number of records, called directory entries. Each entry is a machine-independent representation of the information about an existing file in the directory, including the name, ownership, permission, access dates, and so on.
The entry corresponding to an arbitrary file can be retrieved by stat or fstat (see sys-stat(2)); wstat and fwstat write back entries, thus changing the properties of a file.
New files are made with create and deleted with remove (see sys-open(2) and sys-remove(2)). Directories may not directly be written; create, remove, wstat, and fwstat change them.
A newly spawned thread shares the same address space as that of its creator thread. That is, the set of global variables that is in scope to one is in scope to the other. A change made by one can be detected by the other. Since they are scheduled independently, they should synchronize their actions to share this data coherently.
The newly created thread also shares the same set of open file descriptors and the current working directory.
Processes are also organized into process groups (pgrps) that represent the set of threads of a single application and can be terminated by a single kill request; see prog(3).
A newly-spawned thread automatically inherits the following attributes: file name space (including shared current directory); file descriptor group; and process group. A thread can subsequently acquire a new, independent name space, new or modified file descriptor group, or new process group. See sys-pctl(2).
When a path name crosses from one server to another the process identities are mapped by each server receiving a file request.
The uid and gid strings are assigned to the thread created when a user logs into Inferno and cannot be changed.
From Limbo, system calls that return values on the heap, for instance strings in Dir structures returned by sys-stat(2), and arrays of directory entries returned by sys-readdir(2), can also raise ``out of memory: heap'' exceptions when attempting to create the return value.
|SYS-INTRO(2 )||Rev: Wed Oct 22 21:17:57 GMT 2008|