Chapter 3 

FILES 
=====


   The classes FILE, FILE_SYS and FSYS_DAT actually belong to the 
   BASIC  cluster.  However,  they  are  so  important  that  it seems 
   justifiable to devote an entire chapter to them. 


   Eiffel/S regards files as  persistent dynamic arrays. In particular 
   the class FILE [ G  ] is a generic class just  like ARRAY [ G ] and 
   has a  very similar interface.  One can put  an object x  of type G 
   into the file at index i with  the procedure put (x, i) and one can 
   retrieve the object with the function  item (i). The state size of 
   a file is always the highest index used so far. 


   Note that storing  an Eiffel object  in a file  means that not only 
   the object itself but  also all objects attached  to it by means of 
   its attributes are stored in the file as one ``item''. 


   Here as in  many other situations, however,  the basic classes play 
   an outsider role. A file of type FILE [ CHARACTER ] is in fact just 
   a  stream of  bytes without  any additional  structure. Analogously 
   FILE [ INTEGER ]  and FILE [ REAL ]  are simply streams of integers 
   resp. reals. 


   Please note that strings are not treated like basic objects. A FILE 
   [ STRING ] is not an ordinary ASCII text. 


   It is important to  note that the semantics  of the types ARRAY and 
   FILE do differ in a number of important respects. 

 * One  important difference  between  files and  arrays  concerns the 
   gaps. One can put  an object into a file  at any positive index --- 
   say at 10000. If the highest index used up until then was 100, then 
   the ``space'' between 100 and 10000  will not actually be filled up 
   with anything. The file will only grow by one object. Some internal 
   bookkeeping keeps  track of  the indices  used. With  arrays on the 
   other hand putting  an object at  index 10000 means  that the array 
   has  to  have  been  made  at  least  that  large  in  advance. The 
   intervening slots are filled with default values. 

 * Another difference concerns the behavior  if the function item. If 
   one  repeatedly calls  a.item (i)  for an  array a  and an  index i 
   without doing a put in between, one will always get the same object 
   as result. 


   If one does the same  for a file f one  will get a different object 
   each time. That is,  the objects will not be  the same in the sense 
   of the operator =, although they will  be the same in the sense of 
   equal. 

 * The third difference has to do with different FILE objects that are 
   connected to the same physical  file. The following program excerpt 
   can be used to illustrate the point. 

   f1, f2  : FILE [ COMPLEX ]
   x, y    : COMPLEX
   hook, i : INTEGER 
   hook := system.access_file ("complex.dat", "rw", false) 

   !!f1.connect_to (hook) -- connect  f1 and f2
   !!f2.connect_to (hook) -- to the same physical file 
   ... 
   f1.put (x, i) y := f2.item (i) 

   The result of this operation will be that x and y are equal (in the 
   sense of equal). The reason is that the physical file into which x 
   was put at position i is the  same as that from which y was fetched 
   at position i. 


3.1 Clusters and FILE_SYS 
=========================

   Objects in Eiffel are  usually anonymous. However, when persistence 
   is involved objects  must have some  sort of name,  so that objects 
   created by  one Eiffel process  can be recovered  by another Eiffel 
   process. Files are a  good example of this.  Every file has a name. 
   In addition  Eiffel/S groups  files into  clusters for  purposes of 
   better organization. Clusters are nothing but groups of files. They 
   too have names. Hence  the full designation of a  file is a pair of 
   names 

   (cluster_name, file_name) 

   Two files can have  the same name as long  as they are in different 
   clusters. The names are of type STRING. 


   Of course in order to  make persistence possible some agent outside 
   the Eiffel process must be involved to keep track of the persistent 
   objects. This may be a database  manager or it may be the operating 
   system or some other agent. In the case of the Eiffel/S files it is 
   the operating system that takes care of storing persistent objects. 
   Thus the  Eiffel/S files and  clusters must somehow  be mapped onto 
   corresponding objects  in the  world of  the operating  system. How 
   this  mapping  looks  will  differ  from  one  operating  system to 
   another. Under  UNIX, for  example, the  Eiffel/S files  are mapped 
   onto UNIX files and the Eiffel/S  clusters are mapped onto the UNIX 
   directories.  The same is true for MS-DOS. Hence in these cases the 
   name of a  cluster will in fact  be the path  name of the directory 
   and the  name of  a file  will be  its file  name under  UNIX resp. 
   MS-DOS. 


   Eiffel clusters  are themselves organized  into a  hierarchy in the 
   fashion  that is  usual  in modern  operating  systems. That  is, a 
   cluster  can  have  arbitrarily many  subclusters.  Thus  a cluster 
   possesses two kinds of things: files and subclusters. 


   This hierarchical  organization has consequences  for the structure 
   of a cluster  name. The cluster  name must somehow  describe how to 
   find the cluster within the tree  formed by all clusters. Hence the 
   cluster  name is  a  path whose  components  are the  names  of the 
   subclusters  traversed  in getting  from  the root  cluster  to the 
   cluster being  named. The  individual components  of this  path are 
   separated by the character `/'. This convention will be familiar to 
   all those  users who  have used  UNIX. As  a concession  to MS-DOS 
   programmers the Eiffel/S  file system also  accepts the character ` 
   92 ' as path separator. 


   This also means that each file in the system has a path obtained by 
   appending one more `/' character and then the file name to the path 
   of the cluster containing the file. These paths will play a role in 
   many of the routines described below. 


   We shall often  need to speak of  the prefix and  suffix of a path. 
   The prefix  of a  path is  the path  obtained by  removing the last 
   component. The suffix of the path consists of the last component. 


   Example 

   Given the path 

   /usr/ms/Eiffel/book/chapter2 

   the  prefix  is  the path  
      /usr/ms/Eiffel/book  
   and  the  suffix is 
      chapter2. 


   The prefix always designates a  (potential) cluster. The suffix can 
   designate either a subcluster or a file. 


   The   paths  we  have  been speaking  of  until  now  are so-called 
   absolute paths.  They begin  at the  root cluster  and describe the 
   full path  from the root  to the  subcluster or file  one wishes to 
   specify. 


   It is often  cumbersome working with  absolute paths. Therefore the 
   Eiffel/S file system supports the  notion of the current or working 
   cluster.  There  are  routines (described  below)  for  telling the 
   system which  cluster shall  be the  current cluster.  Then one can 
   also work with so-called relative  paths. These paths do not begin 
   with the character  '/' and describe a  subcluster or file relative 
   to the current cluster. 


Example 

   If the  current cluster has  path /usr/ms/Eiffel  then the relative 
   path book/chapter2  designates the same  subcluster or  file as the 
   absolute path of our example above. 


   The class FILE_SYS is responsible  for the connection of names to 
   objects of type  FILE and the organization  of files into clusters. 
   One can  ask an  object of type  FILE_SYS (there  will usually be 
   only one in an Eiffel program) to give one the list of all files in 
   a  cluster.  Equipped with  the  name of  a  file one  can  use the 
   function 

   access_file (path, permission: STRING; truncate : BOOLEAN) : INTEGER 

   from the  class FILE_SYS  to provide  one with  access to ``the'' 
   physical file belonging to the given path. (The argument permission 
   determines what  one may do  with the  file --- read  or write. The 
   argument truncate determines  whether the file is  to be made empty 
   before  use.) The  function access_file  returns an  integer  (the 
   hook) that can be  used to connect the  Eiffel object of type FILE 
   to the physical file stored by the operating system. This mechanism 
   will be described in more detail shortly. 


   One can use other routines of  the class FILE_SYS to create a new 
   file  or a  new  subcluster, and  to  remove a  file  or subcluster 
   entirely. 


   

3.2 How to use files 
====================

   Before giving  a more  formal description  of the  classes FILE and 
   FILE_SYS let us see how one uses files in a typical situation. It 
   should then be easier to understand the formal description. 


   The steps to be followed in using a file object are the following. 

1. One must  know what  kind of object  one wants  to store  in a file 
   resp. what kind of object is  already stored there. For the sake of 
   this example let  us assume that  we want to  store objects of type 
   COMPLEX. 

2. One then declares an entity of type FILE [ COMPLEX ] --- say 

   my_file : FILE [ COMPLEX ] 


3. Now we need an instance of  the class FILE_SYS in order to access 
   the file system. Here there are at least two possibilities: 

      a) One can inherit from the class FILE_SYS: 

        inherit FILE_SYS end 
        
      b) One can  create a class  containing ``global'' objects 
         provided by once functions: 

        class COMMON 
        feature 
        system : FILE_SYS is 
           once 
              !!result.make 
        end 
        ... 
        end -- class COMMON 

        Then one  inherits from this  class COMMON  whenever one needs 
        the ``global'' objects it provides. 

        inherit COMMON end 

     The second method is the preferred one. 


   * Now one asks the file system to  grant one access to the file and 
     simultaneously connects  it to an  Eiffel object of  type FILE as 
     follows: 

     hook := system.access_file ("complex.dat", "rw", true) 
     !!my_file.connect_to (hook) 


   * At this point one may use the file just as one would an array. 

     my_file.put (some_complex, some_index) 
     some_complex := my_file.item (some_index) 


   * When the  file is  no longer needed  it is  disconnected from the 
     FILE object. 

     my_file.disconnect 

   Note that from  here on it would  be an error to  use put or item 
   with the object my_file without reconnecting it using connect_to. 

     All in all the  use of Eiffel/S files  is quite simple. The large 
   number  of features  in  the class  FILE_SYS  exists to  give the 
   programmer  maximum  control  over the  organization  of  files and 
   clusters. 


   


3.3 FILE 
========

 connect_to (hook : INTEGER) 


Definition 

   Connect the current file object to the physical file represented by 
   hook. 


Preconditions 

   hook must have been obtained from a successful call to the function 
   access_file in FILE_SYS. 


Status 

   Effective creation procedure 


Remarks 

   All Eiffel/S  files (except for  those containing  objects of basic 
   type)  have  internal  information describing  the  type  of object 
   stored in the file. If the internal type of the file represented by 
   hook does not match the type  of current, the call to connect_to 
   will result in an exception. 


   There is in principle  no limit to the  number of file objects that 
   may be simultaneously connected to physical files. Any restrictions 
   the operating system  might impose in  this connection are overcome 
   internally by the Eiffel/S runtime system. 


   disconnect 


Definition 

   Disconnect   the  current  file  object  from  the  physical  file. 
   disconnect has no effect if the file was not connected. 


Preconditions 

   None 


Status 

   Effective procedure 


Remarks 

   Files will automatically be disconnected  at the termination of the 
   Eiffel program if the programmer has forgotten to do so explicitly. 
   It is, however, good  practice to disconnect all  files that are no 
   longer needed, because  this simplifies the  administrative work of 
   the Eiffel/S runtime system. 


   If  an  Eiffel/S  program  terminates  prematurely  because  of  an 
   exception that was not  handled in a rescue  clause, all files will 
   automatically be disconnected.  No information written  to the file 
   during the session will be lost. 


 item (index : INTEGER) : G 


Definition 

   Deliver the  object stored  at position  index in  the file.  If no 
   object has  previously been stored  at that position  the result is 
   the corresponding default value. 


Preconditions 

   The file was successfully connected using connect_to and index >= 
   1. 


Status 

   Effective function 


 put (x : G, index : INTEGER) 


Definition 

   Store the object x at the position index in the file. 


Preconditions 

   The file was successfully connected using connect_to and index >= 1. 


Status 

   Effective procedure 


Remarks 

   As we pointed out in the introductory remarks to this chapter there 
   is no  need to  ``resize'' a  file. One  can put  an object  at any 
   positive index. 


 size : INTEGER 


Definition 

   The maximum index at which an object has so far been put. 


Status 

   Effective state 


Remarks 

   If one creates a file object  f and then executes f.put (x, 100000) 
   the size of the  file will become 100000.  The physical size of the 
   file, however, is likely to be only a few bytes. 


   

3.4 FSYS_DAT 
============


   This class describes the kinds of information that can be requested 
   respectively stored  about a file  or cluster.  Various routines in 
   the class FILE_SYS return objects of type FSYS_DAT. 


   The states of the class are the following. 

 name : STRING -- Name of file  or cluster 

 path : STRING -- Absolute path to file  or cluster

 time  : REAL --  Time of last modification 

 perm : STRING --  Permissions

 count : INTEGER  -- Length of file in bytes or 
                  -- No. files in cluster 

   The  first  two  states  have  already  been  explained  above. The 
   explanation  given for  the state  count in  the comment  should be 
   sufficient. We now describe the other two states. 


   The time associated with a file or  cluster is the time at which it 
   was last modified.  In the case  of clusters ``modification'' means 
   adding or removing  a file or  subcluster from the  cluster. In the 
   case of  a file ``modification''  means putting a  new element into 
   the  file  using the  routine  put  from the  class  FILE.  For an 
   explanation of time in  Eiffel/S see the section  on system time in 
   the chapter on the BASIC cluster. 


   The ``permissions'' associated with a file or cluster determine who 
   may do what with the object. To  this end the world is divided into 
   three categories:  the owner  of the  file, the  work group  of the 
   owner  and the  rest  of the  world.  Permissions can  be specified 
   independently for each of these three categories of user. 


   The owner of  a file is the  user who created  the file using add_ 
   file or access_file.  The members of the  owner's work group are 
   determined  by the  operating system;  this  matter is  outside the 
   control of the Eiffel/S file system. The rest of the world is every 
   user not belonging to the first two categories. 


   Many operating systems  do not support this  division of users into 
   three categories. On  such platforms the  permissions for ``group'' 
   and ``other'' will simply have no significance. 


   The kinds of permissions  that can be granted  to each of the three 
   categories of user differ for  files and for clusters. For clusters 
   the permissions are 

   list (l) modify (m) 

   A user who  has list permission can  execute the routines cluster_ 
   list  and file_list  for the  given cluster.  He can  also obtain 
   information about  the files and  subclusters in  the cluster using 
   cluster_exists, cluster_data etc. 


   A user  who has  modify permission  for a  cluster can  execute the 
   routines add_cluster and remove_cluster  for subclusters of the 
   given cluster as well as  add_file and remove_file for files in 
   the cluster. 


   For files the permissions are 

   read (r) write (w) execute (x) 

   A user with  read permission can  execute the item  routine for the 
   file. With write permission he may execute the put routine. Execute 
   permission only applies to files containing executable programs (or 
   shell scripts) and is not of great importance here. 


   As one sees, the  state perm in FSYS_DAT  is a string. It remains 
   to be explained how this string is constructed. 


   The permission string is divided into three fields corresponding to 
   the  three user  categories. The  fields are  separated by  the dot 
   character '.'.  The fields  in the  permission string  for clusters 
   consist of at most two of the characters 'l', 'm' or '-'. If an 'l' 
   is present list permission is granted.  If an 'm' is present modify 
   permission is granted. A '-'  means the corresponding permission is 
   denied. The 'l' always precedes the corresponding 'm'. 


Example 

   The permission string  "lm.l-.--" means that the  owner may list or 
   modify the cluster, the  members of his group  may list the cluster 
   but may not modify it and the  rest of the world has no permissions 
   at all with respect to this cluster. 


   The permission  string for  files is  similarly divided  into three 
   fields  separated by  the  dot character  '.'.  Each of  the fields 
   consists of at most three of  the characters 'r', 'w', 'x' and '-'. 
   If  an 'r'  is  present the  corresponding  user category  has read 
   permission. If a 'w' is present the users have write permission and 
   an 'x' has the  same meaning for execution  permission. A '-' means 
   the corresponding  permission is  denied. The  characters appear in 
   the order 'r', 'w' and 'x' from left to right. 


Example 

   The string "rwx.r-x.--x"  means the owner may  do anything with the 
   file, his group  may read or execute  it and the  rest of the world 
   may only execute it. 


   Ellisions  are allowed.  Missing characters  in a  field are  to be 
   understood  as  '-'.  Thus we  could  have  written  the permission 
   strings in the examples above  as "lm.l." resp. as "rwx.rx.x". One 
   may even leave out the  right--most fields if they consist entirely 
   of dashes. Thus "rw" is shorthand for "rw-.---.---". 




3.5 FILE_SYS 
============



   In describing the features of the class FILE_SYS it is convenient 
   to group  them into  various categories.  There are  three kinds of 
   features. 

 * Those that have mainly to do with clusters. 

 * Those that have mainly to do with files. 

 * Those that manipulate paths. 
     Each of the following subsections treats one of these categories. 


   

3.6 The clusters 
================


   The features of FILE_SYS that deal directly with clusters are the 
   following. 

 current_cluster  :  STRING

 parent_cluster   :  STRING

 change_cluster (path : STRING) 

 add_cluster (path, perms : STRING)

 remove_cluster (path : STRING) 

 cluster_data  (path : STRING)  : FSYS_DAT
  
 cluster_list  (path : STRING) : S_LIST [ FSYS_DAT ]
 
 cluster_exists  (path :  STRING) :  BOOLEAN

 cluster_time  (path :  STRING)  : REAL  

 cluster_perm  (path :   STRING) :  STRING 

 my_cluster_perm (path  :  STRING) :  STRING

 has_listperm  (path : STRING) :   BOOLEAN 

 has_modperm  (path  : STRING)  :  BOOLEAN 

 cluster_count (path  : STRING)  : INTEGER 

 subcluster_count (path : STRING) : INTEGER 

 change_cluster_perm (path, new_perms : STRING) 

   The first three features have to do with the concept of ``current'' 
   or ``working'' cluster.  current_cluster is the  absolute path of 
   the current cluster.  parent_cluster is the  absolute path of the 
   parent cluster of the  current cluster --- i.e.  of the cluster one 
   step  nearer  to  the root  cluster.  With  the  procedure change_ 
   cluster one can alter the current cluster. With the instruction 

 change_cluster (parent_cluster) 

   one can climb one step up in the cluster tree. 

   The next two procedures  have an obvious meaning:  one can use them 
   to create and remove clusters from the file system. 

   The two functions cluster_data and  cluster_list can be used to 
   obtain information about a cluster. The function cluster_data (p) 
   returns an  object of type  FSYS_DAT describing  the cluster with 
   path p. The  function cluster_list (p) returns  a sorted list of 
   such objects, one for each subcluster of the cluster with path p. 


   The  next  group  of  routines  represent  so-called ``convenience 
   functions''. They are not strictly necessary, since the information 
   they provide could  be obtained using  cluster_data and cluster_ 
   list. However, they  save the programmer the  trouble of picking a 
   piece of information out of an object of type FSYS_DAT. 


   Finally with  the procedure  change_cluster_perm one  can alter 
   the permissions of  a cluster --- provided  one has the permissions 
   needed to do so! This means being owner of the cluster. 


 make 


Definition 

   Initialize the file system. 


Preconditions 

   None 


Status 

   Effective creation procedure 


 add_cluster (path, permissions : STRING) 


Definition 

   Create a new cluster whose path is path. 


Preconditions 

   The user  has modify  permission in  the cluster  to which  the new 
   cluster is to be added. 


Status 

   Effective procedure 


 change_cluster (path : STRING) 


Definition 

   Change current cluster to cluster with path path. 


Preconditions 

   None 


Status 

   Effective procedure 


 change_cluster_perm (path, new_perms : STRING) 


Definition 

   Change permissions of cluster with path path to new_perms. 


Preconditions 

   The user is owner of the cluster. 


Status 

   Effective procedure 


 cluster_count (path : STRING) : INTEGER 


Definition 

   Number of files in cluster with path path. 


Preconditions 

   None 


Status 

   Effective function 


 cluster_data (path : STRING) : FSYS_DAT 


Definition 

   Get all information available about the cluster with path path. 


Preconditions 

   None 


Status 

   Effective function 


 cluster_exists (path : STRING) : BOOLEAN 


Definition 

   Does a cluster with path path exist? 


Preconditions 

   None 


Status 

   Effective function 


 cluster_list (path : STRING) : S_LIST [ FSYS_DAT ] 


Definition 

   Deliver a sorted list of all  subclusters of the cluster whose path 
   is path. The list is sorted by cluster name. 


Preconditions 

   None 


Status 

   Effective function 


 cluster_perm (path : STRING) : STRING 


Definition 

   All permissions for the cluster with path path. 


Preconditions 

   None 


Status 

   Effective function 


 cluster_time (path : STRING) : REAL 


Definition 

   Last modification time of the cluster with path path. 


Preconditions 

   None 


Status 

   Effective function 

     
 current_cluster : STRING 


Definition 

   The absolute path of the current cluster. 


Status 

   Effective state 


 has_listperm (path : STRING) : BOOLEAN 


Definition 

   May I list the cluster with path path? 


Preconditions 

   None 


Status 

   Effective function 


Remarks 

   ``List''  means  executing cluster_list  or  file_list  for the 
   cluster or cluster_data, file_data or one of the corresponding 
   convenience functions for a file or subcluster of the cluster. 


 has_modperm (path : STRING) : BOOLEAN 


Definition 

   May I modify the cluster with path path? 


Preconditions 

   None 


Status 

   Effective function 


Remarks 

   ``Modify'' means executing add_cluster, remove_cluster, add_ 
   file or remove_file for the cluster. 


 my_cluster_perm (path : STRING) : STRING 


Definition 

   What permissions do  I have with  respect to the  cluster with path 
   path? 


Preconditions 

   None 


Status 

   Effective function 


Remarks 

   The result will be one of the strings "", "l", "m" or "lm". 


 parent_cluster : STRING 


Definition 

   The absolute path of the parent  cluster of the current cluster. If 
   the current  cluster is  the root  cluster then  parent_cluster = 
   void. 


Status 

   Effective state 


 remove_cluster (path : STRING) 


Definition 

   Eliminate the cluster with path path. 


Preconditions 


  1. The process must have modify permission for the parent cluster of 
     the cluster to be removed. 

  2. sub_cluster_count (path) = 0 

  3. cluster_count (path) = 0 


Status 

   Effective procedure 


 subcluster_count (path : STRING) 


Definition 

   Number of subclusters in cluster with path path. 


Preconditions 

   None 


Status 

   Effective function 


   


3.7 The files 
=============


   The features  of FILE_SYS that  deal directly with  files are the 
   following. 


 access_file (path, permissions :  STRING, truncate : BOOLEAN) : INTEGER

 add_file (path, permissions : STRING)

 remove_file (path : STRING) 

 file_list (path : STRING) : S_LIST [ FSYS_DAT ]

 file_data (path : STRING) : FSYS_DAT
 
 file_exists (path : STRING) : BOOLEAN

 file_time (path : STRING) : REAL 
 
 file_perm  (path  : STRING)  :  STRING 
 
 my_file_perm  (path : STRING) : STRING 

 has_readperm  (path  : STRING) : BOOLEAN
 
 has_writeperm  (path  :  STRING) :  BOOLEAN 

 has_execperm  (path :  STRING) : BOOLEAN

 file_count (path : STRING) : INTEGER 

 change_file_perm (path, new_permissions : STRING) 


 The first  of these  is in a  sense the  most important;  it is the 
 function used to  access a physical  file and connect  it to a file 
 object as explained at the beginning of this chapter. 


   The meaning  of the  next two  features is  self--evident. They are 
   used to create and destroy files. file_list returns a sorted list 
   of all files in the cluster whose path is path. (One could in fact 
   argue that  this function really  belongs to the  previous group of 
   features.) The  function file_data  (path) returns  all available 
   information about the file whose path is path. 


   The next group  of features consists  of convenience functions. The 
   information they  provide could in  principle be  obtained by using 
   file_data and file_list, but  these functions can simplify the 
   life of the programmer. 


   The final feature can be used  to alter the permissions attached to 
   a file ---  provided the user  has the necessary  permissions to do 
   this. One must have modify permission  for the cluster to which the 
   file belongs. 



 access_file (path, perms : STRING, trunc : BOOLEAN) : INTEGER 


Definition 

   Make access to the file with  path path available. If the file does 
   not yet exist, create it. The  argument perms describes the kind of 
   operations to be  performed on the  file: "r" means  read only, "w" 
   means write only and "rw" means both.  If trunc is true the file is 
   made to  be empty  before returning  access; otherwise  the file is 
   left as it is  found. The value returned is  a ``hook'' that can be 
   passed to the procedure connect_to in the class FILE. 


Preconditions 

   The preconditions for this function  are complex. Suffice it to say 
   that path must  describe a valid  path and that  the user must have 
   the  necessary  permissions.  In  particular  he  must  have modify 
   permission in the given cluster if  the file does not yet exist and 
   must be created. Also the operations  announced by perms must be in 
   accord with the permissions the user actually has. 


Status 

   Effective function 


Remarks 

   If access_file is called with perms  = "r" then a subsequent call 
   to  put for  the file  object  attached to  the physical  file with 
   connect_to will cause an exception. The same is true of a call to 
   item if the file was accessed with perms = "w". 



 add_file (path, perms : STRING) 


Definition 

   Create a  new (empty)  file with  path path.  The file  shall have 
   permissions equal to perms. 


Preconditions 

   The user must  have modify permission  in the cluster  in which the 
   file is to be created. 


Status 

   Effective procedure 


 change_file_perm (path, new_perms : STRING) 


Definition 

   Change the permissions  attached to the  file with path  path to be 
   new_perms. 


Preconditions 

   The user must be owner of the file. 


Status 

   Effective procedure 


 file_count (path : STRING) : INTEGER 


Definition 

   Number of bytes in the physical file whose path is path. 


Preconditions 

   None 


Status 

   Effective function 


 file_data (path : STRING) : FSYS_DAT 


Definition 

   All the information available about the file with path path. 


Preconditions 

   None 


Status 

   Effective function 


 file_exists (path : STRING) : BOOLEAN 


Definition 

   Is there a file with path path? 


Preconditions 

   None 


Status 

   Effective function 


 file_perm (path : STRING) : STRING 


Definition 

   The complete permission string for the file with path path. 


Preconditions 

   None 
  Status 

   Effective function 


 file_time (path : STRING) : REAL 


Definition 

   The last modification time for the file with path path. 


Preconditions 

   None 


Status 

   Effective function 


 has_execperm (path : STRING) : BOOLEAN 


Definition 

   May the user execute the file with path path? 


Preconditions 

   None 


Status 

   Effective function 


 has_readperm (path : STRING) : BOOLEAN 


Definition 

   May the user read the file with path path (i.e. execute item)? 


Preconditions 

   None 


Status 

   Effective function 


 has_writeperm (path : STRING) : BOOLEAN 


Definition 

   May the user write to the file with path path (i.e. execute put)? 


Preconditions 

   None 


Status 

   Effective function 


 my_file_perm (path : STRING) : STRING 


Definition 

   What permissions do I have with  respect to the file with path path 
   ? 


Preconditions 

   None 


Status 

   Effective function 


Remarks 

   The result will be one of the strings "", "r", "w", "x", "rw", 
   "rx", "wx", "rwx". 


 remove_file (path : STRING) 


Definition 

   Eliminate the file with path path. 


Preconditions 

   The user must have modify permission for the cluster containing the 
   file to be removed. 


Status 

   Effective procedure 


   

3.8 The paths
============= 

   Building and parsing  paths is a tedious  and error--prone task for 
   the programmer. To make life easier  in this respect the class FILE 
   _SYS provides a  number of convenience  functions for manipulating 
   paths. 

   path_suffix (path : STRING) :  STRING path_prefix (path : STRING) : 
   STRING concat_paths (path1, path2  : STRING) : STRING absolute_path 
   (path  :  STRING) :  STRING  same_path  (path1, path2  :  STRING) : 
   BOOLEAN 



 absolute_path (path : STRING) : STRING 


Definition 

   Build an absolute path out of the (possibly relative) path path. 


Preconditions 

   None 


Status 

   Effective function 


 concat_paths (path1, path2 : STRING) :STRING 


Definition 

   Create concatenated path out of path1 and path2. 


Preconditions 

   None 


Status 

   Effective function 


Remarks 

   This convenience function saves the  user the annoyance of fumbling 
   with the `/' character. 


 path_prefix (path : STRING) : STRING 


Definition 

   Extract the prefix of the path path. 


Preconditions 

   None 


Status 

   Effective function 


 path_suffix (path : STRING) : STRING 


Definition 

   Extract the suffix of the path path. 


Preconditions 

   None 


Status 

   Effective function 


 same_path (path1, path2 : STRING) : BOOLEAN 


Definition 

   Do the two paths path1 and  path2 describe the same object (file or 
   cluster)? 


Preconditions 

   None 


Status 

   Effective function 


Remarks 

   This is not the  same as asking if the  two strings path1 and path2 
   are  equal  (path1.is_equal  (path2)).  If  one  of  them  is a 
   relative path and the  other an absolute path,  the answer could be 
   ``yes'' even though the strings  are not equal. Moreover under UNIX 
   the answer could be ``yes'' even though the strings look completely 
   different; this is because of the links that UNIX supports. 


