next up previous contents index
Next: Opening and Examining Directories Up: The OS Interface: Files Previous: Manipulating Open-File State

Manipulating File Attributes

  While the main purpose of a file is either to provide storage (regular files) or to provide a uniform input/output interface (device files and pipes), there are some miscellaneous attributes associated with each file. The procedures in this subsection allow examining and modifying those attributes.

                                 

TYPE
  FileType =
    (FTDirectory,
     FTLink, (* symbolic link *)
     FTRegular, (* disk file *)
     FTStructured, (* none on Taos *)
     FTUnstructured, (* so-called character device *)
     FTPipe, (* pipe *)
     FTSocket, (* socket--none on Taos *)
     FTFIFO); (* System V named pipe--none on Taos *)
  FileClass = SET OF FileType;

CONST
  FCLeaf = FileClass{FTRegular .. FTFIFO};
  FCDevice = FileClass{FTStructured, FTUnstructured};

   

TYPE
  Major = CARDINAL;
  Minor = CARDINAL;

For each device file (FCDevice) there are two identifying values of type Major and Minor. Major maps onto a device driver, while Minor indicates a particular instance.

Ultrix note: Instances of Major and Minor always have values less than 256.

  Taos note: Devices with values larger than 256 are truncated when examined by programs using the Ultrix kernel-call interface.

 

TYPE
  VID = RECORD p: UID.Constant; t: UID.Counter; END;

  A VID identifies a logical volume.

  Taos note: A VID is equivalent to a LocalFile.ID.

 

  FileInfo = RECORD
    size: CARDINAL;
    length: CARDINAL;

    atime: Time.T;
    ctime: Time.T;
    mtime: Time.T;

    mode: FileMode;

    nLinks: CARDINAL;

    CASE fileType: FileType OF
    | FTStructured, FTUnstructured: major: Major; minor: Minor;
    ELSE
    END;

    instance: Text.T;
    vid: VID;
    fileSeq: CARDINAL;
    fileBlock: CARDINAL;

    owner: Text.T;
    group: Text.T;
  END; (* FileInfo *)

A FileInfo record packages the attribute information available about a file via the GetInfo and PGetInfo procedures.

The length of a file gives the number of bytes logically contained in the file: it is the position at which Read reports end of file. The size gives the number of bytes currently allocated to the file, in anticipation of further growth.

      The atime field records when the file was last accessed (read or written). The mtime field records when the file was last modified (written, or changed in length). The ctime field records when some attribute of the file was last changed (by any of the procedures in this section, or those in Section 4.8, page [*] that affect fields of the FileInfo record).

The mode field gives the access mode and miscellaneous file state (mainly SetUIDonExec).

    The nLinks field counts the total number of directory entries (hard links) pointing to this file. It may be an overestimate if the volume needs scavenging.

The fileType field specifies what kind of file this is. For device files, the major and minor fields determine the device driver and instance of that device type.

  The instance, vid, fileSeq, and fileBlock fields map the file onto the underlying representation. The instance field is NIL if the file resides on the local machine, otherwise it specifies the instance of the remote file service used to access the file. There may be more than one such instance serving a particular volume, so the instance field is not a substitute for the vid field in testing whether two remote disk files are the same.

  The vid field specifies the logical volume on which the file resides; it is unique across all machines.

    The fileSeq field is a unique identifier for the file within its volume. On Ultrix, the number may eventually be reused (it is known as an inode number); on Taos, it is unique for all time. Two regular files are identical if and only if they have the same vid and fileSeq values.

On Taos, the fileBlock field specifies the logical block number within the volume on which the file begins. On Ultrix, this field is always zero.

The owner field specifies the user name of the owner of the file; the group field specifies the name of the group of users that is singled out to receive special access to the file (see the discussion of access modes on page [*]).

 

PROCEDURE GetInfo(
    f: File;
    VAR (* OUT *) info: FileInfo;
    returnNames: BOOLEAN := TRUE)
  RAISES {Error};
  (* BadFileEC, RemoteFileEC, IOErrorEC, PvOfflineEC *)

 

PROCEDURE PGetInfo(
    dir: Dir;
    path: PathName;
    VAR (* OUT *) info: FileInfo;
    follow: BOOLEAN := TRUE;
    returnNames: BOOLEAN := TRUE;
    euser: User := NIL)
  RAISES {Error}; (* NotSuperUserEC, PathES, FailureES? *)

  GetInfo and PGetInfo return information about a file. GetInfo accepts a file handle for an open file, while PGetInfo accepts the path name of a file. If the file is actually a symbolic link and follow is FALSE, then PGetInfo returns information about the link itself rather than its referent.

  If returnNames is TRUE, the owner and group fields are filled in; otherwise they are set to NIL. (This is an optimization to avoid reading /etc/passwd in the Ultrix emulation and to avoid an allocation.)

PGetInfo interprets the euser parameter the same way Open does.

 

PROCEDURE SetLength(f: File; length: CARDINAL)
  RAISES {Error};
  (* BadFileEC, InvalidObjectEC, IOErrorEC, PvOfflineEC,
     RemoteFileEC, NotEnoughRoomEC *)

 

PROCEDURE PSetLength(
    dir: Dir;
    path: PathName;
    size: CARDINAL;
    euser: User := NIL)
  RAISES {Error};
  (* NotSuperUserEC, PathES, InvalidObjectEC, NotEnoughRoomEC,
     FailureES? *)

SetLength and PSetLength set the length of the file, that is the point at which Read and FRead report end of file, to the specified number of bytes. If the length increases, the size, that is the number of bytes actually allocated, is increased to that needed to hold the new length and each new byte is set to zero. Decreasing the length has no effect on the size, so usually SetSize or PSetSize should be called afterward. See SetSize and PSetSize below.

SetLength does nothing if f refers to a device; it raises InvalidObjectEC if f refers to a pipe or socket. PSetLength raises InvalidObjectEC if the path name specifies anything other than a regular file.

PSetLength interprets the euser parameter the same way Open does.

  

PROCEDURE SetSize(f: File; size: CARDINAL)
  RAISES {Error};
  (* BadFileEC, InvalidObjectEC, IOErrorEC, PvOfflineEC,
     RemoteFileEC, NotEnoughRoomEC *)

 

PROCEDURE PSetSize(
    dir: Dir;
    path: PathName;
    size: CARDINAL;
    euser: User := NIL)
  RAISES {Error};
  (* NotSuperUserEC, PathES, InvalidObjectEC, InvalidArgumentEC,
     NotEnoughRoomEC, FailureES? *)

SetSize and PSetSize reserve enough storage for a file so that it can grow to a specified number of bytes in length. SetSize accepts a file handle for an open file, while PSetSize accepts the path name of a file.

SetSize and PSetSize do nothing if f refers to a device or to a file residing on an Ultrix machine. SetSize raises InvalidObjectEC if f refers to a pipe or socket.

If a program can estimate the eventual length of a file it will be writing, setting the size after opening the file serves to check whether sufficient disk space exists and to reserve it for the specified file. This contributes towards minimizing the fragmentation of disk space.

SetSize and PSetSize raise InvalidArgumentEC if the new size is less than the current length of the file.

PSetSize interprets the euser parameter the same way Open does.

Taos note: Setting the size explicitly is an optimization for use by programmers trying to use disk space carefully. Taos automatically increases the size when a SetLength or a write past the current size occurs. When the last open-file object for a file is deleted, Taos automatically decreases the size to the minimum needed to hold the length if and only if the last size-setting operation was an automatic one.

Ultrix note: SetSize and PSetSize are ignored.

    

PROCEDURE GetDevPGRP(f: File): PGRP RAISES {Error};
  (* InvalidObjectEC, BadPIDEC *)

PROCEDURE SetDevPGRP(f: File; pgrp: PGRP) RAISES {Error};
  (* InvalidObjectEC *)

    GetDevPGRP and SetDevPGRP get and set the distinguished process group associated with a device. If the file is not a device, GetDevPGRP and SetDevPGRP raise InvalidObjectEC. If the file is a device whose process group hasn't yet been set, GetDevPGRP raises BadPIDEC.

See the discussion of job control in Section 2.11, page [*].

 

PROCEDURE SetMode(
    f: File;
    mode: FileMode;
    euser: User := NIL)
  RAISES {Error};
  (* NotSuperUserEC, BadFileEC, NotOwnerEC,
     IOErrorEC, PvOfflineEC, RemoteFileEC *)

 

PROCEDURE PSetMode(
    dir: Dir;
    path: PathName;
    mode: FileMode;
    euser: User := NIL)
  RAISES {Error};
  (* NotSuperUserEC, PathES, NotOwnerEC, FailureES? *)

        SetMode and PSetMode set the file mode of a file. SetMode accepts a file handle for an open file, while PSetMode accepts the path name of a file or directory. The file mode contains the access mode, controlling which processes can access the file, and also contains the FileState (e.g., the SetUIDonExec flag).

These procedures raise NotOwnerEC unless the calling process is the owner of the file or is the super-user.

SetMode and SetMode interpret the euser parameter the same way Open does.

Note that changing the owner of a file or opening it for writing clears the SetUIDonExec flag.

 

PROCEDURE SetOwner(
    f: File;
    owner: Text.T;
    group: Text.T;
    euser: User := NIL)
  RAISES {Error};
  (* NotSuperUserEC, BadFileEC, InvalidObjectEC,
     NowOwnerEC, FailureES? *)

 

PROCEDURE PSetOwner(
    dir: Dir;
    path: PathName;
    owner: Text.T;
    group: Text.T;
    euser: User := NIL)
  RAISES {Error};
  (* NotSuperUserEC, PathES, NotOwnerEC, FailureES? *)

    SetOwner and PSetOwner set the owner and user group of a file, and also clear the SetUIDonExec flag. SetOwner accepts a file handle for an open file, and raises InvalidObjectEC unless it refers to a regular file or device. PSetOwner accepts the path name of a file, directory, or symbolic link.

Specifying NIL for owner or group means to leave it as it stands. A process must be the super-user to change the owner, otherwise NotSuperUserEC is raised. A process must either be the super-user or must be both the owner of the file and a member of the new group to change the user group, otherwise NotOwnerEC is raised.

SetOwner and PSetOwner interpret the euser parameter the same way Open does.

Ultrix note: SetOwner and PSetOwner also clear the SetGIDonExec flag.

 

PROCEDURE PAccess(
    dir: Dir;
    path: PathName;
    euser: User := NIL)
    : FileAccessMode
  RAISES {Error};
  (* NotSuperUserEC, PathES, FailureES? *)

  PAccess determines the FileAccessMode that the calling process would have for the specified file: a subset of rOK, wOK, and xOK. PAccess raises LookUpEC if the file doesn't exist, but it only raises ProtectionViolationEC if the caller has insufficient privileges to access the prefix of the specified path name leading up to the final directory.

PAccess interprets the euser parameter the same way Open does.

 

PROCEDURE PGetLink(
    dir: Dir;
    path: PathName;
    euser: User := NIL)
    : Text.T
  RAISES {Error};
  (* NotSuperUserEC, PathES, InvalidArgumentEC, FailureES? *)

  PGetLink returns the value of the symbolic link with the specified path name; it raises InvalidArgumentEC if the path name doesn't specify a symbolic link.

PGetLink interprets the euser parameter the same way Open does.

 

PROCEDURE PSetTimes(
    dir: Dir;
    path: PathName;
    atime: Time.T;
    mtime: Time.T;
    euser: User := NIL)
  RAISES {Error};
  (* NotSuperUserEC, PathES, NotOwnerEC, FailureES? *)

      PSetTimes sets the access and modification times of the file to the specified values, and sets the attribute-change time (ctime) of the file to the current time. It raises NotOwnerEC if called by other than the super-user or the owner of the file.

PSetTimes interprets the euser parameter the same way Open does.

  

PROCEDURE IOCtl(
    f: File;
    operation: UNSIGNED;
    VAR (* IN and/or OUT *) argument: ARRAY OF System.Byte)
  RAISES {Error, Alerted};
  (* BadFileEC, InvalidArgumentEC, OperationConflictEC,
     InvalidObjectEC, BadIOCtlOpEC, IOErrorEC,
     PvOfflineEC, RemoteFileEC *)

IOCtl performs a device-specific operation on the device underlying the file handle f. It raises BadIOCtlOpEC if f doesn't refer to a device or if f refers to a device but the operation does not apply to the particular device type. It raises InvalidArgumentEC if the `argument' parameter does not meet the requirements (size or value) of the specified operation.

      See the documentation of the specific device for details about the operations and their arguments, e.g., tty(4). The IOCtl and TtyDevice interfaces contain Modula-2+ types and constants for use with the IOCtl procedure.

No currently implemented IOCtl operations are actually alertable.

Taos note: The only commands that are implemented are the Ultrix device-specific commands for which OS provides no specialized procedure (e.g., GetDevPGRP). This excludes FIOCLEX/FIONCLEX, FIOGETOWN/FIOSETOWN, FIOASYNC, FIONBIO, FIONREAD, TIOCNXCL/TIOCEXCL, TIONOTTY, and TIOCGPGRP/TIOCSPGRP.


next up previous contents index
Next: Opening and Examining Directories Up: The OS Interface: Files Previous: Manipulating Open-File State
Paul McJones
8/28/1997