next up previous contents index
Next: Manipulating File Attributes Up: The OS Interface: Files Previous: Manipulating File Handles

Manipulating Open-File State

Each procedure in this subsection examines or modifies state maintained in an open-file object (see page [*]). Recall that separate calls to Open always produce separate open-file objects, but different file handles may share (i.e., refer to) the same open-file object. Sharing results from using the Dup procedure (within a single process) or from using the SetDescriptor and GetDescriptor procedures (across two or more processes); see Section 4.4, page [*].

   

TYPE
  SeekCmd = (SeekSet, SeekIncr, SeekExtend);

PROCEDURE Seek(
    f: File;
    value: INTEGER;
    whence: SeekCmd := SeekSet)
    : CARDINAL
  RAISES {Error};
  (* UnseekableObjectEC, InvalidArgumentEC, RemoteFileEC *)

  Seek sets the file pointer contained in the open-file object referred to by f, and returns the new value of the file pointer. The new value is determined in one of three ways: by specifying an absolute position (SeekSet, the default), by adding a signed offset to the current value (SeekIncr), or by adding a signed offset to the current end of file (SeekExtend). Seek raises InvalidArgumentEC if the new pointer (as specified by value and whence) would be negative. Seek never changes the length of the file, although a subsequent Write (or Copy) will lengthen the file if the Seek moved the file pointer past the end of file.

Consider using FRead and FWrite (see page [*] and following) instead of Seek, especially if it would be useful to allow multiple threads to share the same file handle (recall that advisory locks are held by open-file objects).

Seek does nothing (and returns 0) if f is a device; it raises UnseekableObjectEC if f refers to a pipe.

        

TYPE
  LockArg = (Unlocked, SharedLock, ExclusiveLock);

PROCEDURE GetLock(f: File): LockArg RAISES {Error};
  (* BadFileEC, InvalidObjectEC, RemoteFileEC *)

PROCEDURE SetLock(
    f: File;
    lock: LockArg;
    noBlock: BOOLEAN := FALSE)
  RAISES {Error, Alerted};
  (* BadFileEC, InvalidObjectEC, WouldBlockEC, RemoteFileEC *)

GetLock returns the current setting, and SetLock changes the setting, of the advisory lock held by the open-file object referred to by f. The file should be a regular file. If it is a pipe or socket, GetLock and SetLock raises InvalidObjectEC.

SetLock attempts to obtain the specified advisory lock for the open-file object referred to by f. If there is no conflict for the lock, SetLock succeeds and returns immediately. The action SetLock takes when the requested lock conflicts with a lock already held by a different open-file object for the same file depends on the value of the noBlock parameter. If it is FALSE, SetLock blocks until the conflict goes away; if it is TRUE, SetLock raises WouldBlockEC. SetLock is alertable while blocked.

  SetLock can be used to change an existing lock from a SharedLock to an ExclusiveLock, or vice versa. In such a case, SetLock does not first release the existing lock. (This is in contrast to the Ultrix flock kernel call.) Downgrading an ExclusiveLock to a SharedLock always succeeds immediately. Upgrading a SharedLock to an ExclusiveLock blocks as long as any other open-file object for the same file holds a SharedLock.

Advisory locks are intended to be used by cooperating processes. They are called advisory because they do not affect non-cooperating processes. Thus it only makes sense to use an advisory lock on a file when it is known that all programs that read or write the file also use an advisory lock on it.

It is not a good idea to set an advisory lock on a device, as the lock is obtained on the file used to open the device (for example /dev/magtape) rather than on the instance of the device itself (for example the device with a certain major and minor device type). Tty devices are conventionally `locked' by changing the owner of the device.

          

TYPE
  SettableHandleMode = BITS 16 FOR SET OF [fAppend .. fAsync];

PROCEDURE SetFlags(f: File; flags: SettableHandleMode)
  RAISES {Error}; (* BadFileEC *)

SetFlags sets several of the flags in the open-file object referred to by the file handle f. The meaning of the flags is as follows:

fAppend:
Force all writes to regular files to the end of the file; fAppend is ignored for other types of files.  

fNoDelay:
Put pipes, devices, and sockets into a state such that reads or writes through the Ultrix kernel-call interface return an error (EWOULDBLOCK) instead of blocking. This does not affect OS procedures (i.e., Read, Write, Copy, Wait). It is only present in the OS interface for use by processes sharing file descriptors with Ultrix processes via the SetDescriptor procedure (see page [*]).          

fAsync:
Cause a signal (SigIO) to be sent to the process group associated with the device when I/O is possible. SigIO cannot be handled by a client of OS; the fAsync flag is provided only for use by processes sharing file descriptors via the SetDescriptor procedure (see page [*]).        

             

TYPE
  HandleMode = BITS 16 FOR SET OF [fRead .. fAsync];

PROCEDURE GetFlags(f: File): HandleMode
  RAISES {Error}; (* BadFileEC *)

GetFlags returns the flags associated with the open-file object referred to by f. These are all the flags settable with SetFlags and with Open.


next up previous contents index
Next: Manipulating File Attributes Up: The OS Interface: Files Previous: Manipulating File Handles
Paul McJones
8/28/1997