#line 191 "/home/travis/build/felix-lang/felix/src/packages/filesystem.fdoc"
  
  Filesystem file kind query functions parametrised
  by operating system, status type and mode type.
  class FileStat_class[OS,stat_t, mode_t]
  {
    Get information about a file into a status buffer.
    Sets error code at argument 3 pointer.
    virtual proc stat: string * &stat_t * ∫
  
    set access and modification time of a file.
    Sets error code at argument 4 pointer.
    Times are in seconds, nominally from Epoch (Jan 1 1970).
    virtual proc utime: string * double * double * ∫
  
    Change read,write permissions for group, owner etc.
    Return 0 on success.
    On Windows this function may silently fail to obey
    unsupported operations.
    virtual gen chmod: string * mode_t -> int;
  
    set mask for subsequent permissions.
    On Windows this function may silently fail to obey
    unsupported operations.
    virtual gen umask: mode_t -> mode_t;
  
    Abstracted platform independent file type taxonomy.
    union file_type_t =
      | PIPE
      | STREAM
      | DIRECTORY
      | BLOCK
      | REGULAR
      | SYMLINK
      | SOCKET
      | INDETERMINATE
      | NONEXISTANT
      | NOPERMISSION
    ;
  
    Get the file type from a file stat buffer.
    virtual fun file_type: &stat_t -> file_type_t;
  
    Fill a stat buffer with information about a file.
    gen stat(file: string, statbuf:&stat_t) = {
      var res: int;
      stat(file, statbuf, &res);
      return res == 0;
    }
  
    Get a file last modification time from a stat buffer.
    Time is in seconds.
    fun mtime: &stat_t -> double = "(double)($1->st_mtime)";
  
    Get a file creation time from a stat buffer.
    Note: not available on Unix.
    Time is in seconds.
    fun ctime: &stat_t -> double = "(double)($1->st_ctime)";
  
    Get modification time of a file by name.
    Time is in seconds.
    fun filetime(f:string):double =
    {
      var b: stat_t;
      var err:int;
      stat(f,&b,&err);
      return if err == 0 then mtime (&b) else 0.0 endif;
    }
  
    Set the last access and modification time of a file by name.
    gen utime(f:string, a:double, m:double): bool = {
      var r:int;
      utime(f,a,m,&r);
      return r == 0;
    }
  
    Set the last access and modification time of a file by name,
    where the two times are given by a single argument.
    gen utime(f:string, t:double) => utime(f,t,t);
  
    Check if a file exists.
    fun fileexists(f:string):bool=> filetime f != 0.0;
  
    Find the type of a file.
    fun filetype(f:string):file_type_t =
    {
      var b:stat_t;
      var err:int;
      stat(f,&b,&err);
      return
        if err == 0 then file_type (&b)
        elif errno == EACCES then NOPERMISSION
        elif errno == ENOENT then NONEXISTANT
        else INDETERMINATE
        endif
      ;
    }
  
    fun past_time () => -1.0;
    fun future_time () => double(ulong(-1)); // a hacky way to get a big number
  
    fun strfiletime0 (x:double) = {
      return
        if x == #past_time then "BIG BANG"
        elif x == #future_time then "BIG CRUNCH"
        else fmt (x, fixed (0,3))
        endif
      ;
    }
  
    fun strfiletime (x:double) = {
      assert x != 0.0;
      return strfiletime0 x;
    }
  
    fun dfiletime(var f:string, dflt:double)=
    {
      var x = FileStat::filetime (f);
      x = if x == 0.0 then dflt else x endif;
      //debugln$ "Time of file '" + f + "' is " + strfiletime x;
      return x;
    }
  
  
  }
  
  Platform dependent operations for host file system.
  class FileStat {
  if PLAT_WIN32 do
    inherit Win32FileStat;
  else
    inherit PosixFileStat;
  done
  }