#line 327 "/home/travis/build/felix-lang/felix/src/packages/filesystem.fdoc"
  
  class PosixFileStat
  {
    pod type stat_t = "struct stat" requires Posix_headers::sys_stat_h;
  
    pod type mode_t = "mode_t" requires Posix_headers::sys_types_h;
    instance Bits[mode_t] {} // defaults to C operators
    instance Eq[mode_t] { fun == : mode_t * mode_t -> bool = "$1==$2"; }
    open Eq[mode_t];
    open Bits[mode_t];
  
    //------------------------------------------------------------
    // file mode: type and permissions
    //------------------------------------------------------------
    // file types
    const S_IFMT  : mode_t; // file type mask
    const S_IFIFO : mode_t;
    const S_IFCHR : mode_t;
    const S_IFDIR : mode_t;
    const S_IFBLK : mode_t;
    const S_IFREG : mode_t;
    const S_IFLNK : mode_t;
    const S_IFSOCK: mode_t;
  
    // permissions
    const S_IRWXU : mode_t; // RWX mask: owner
    const S_IRUSR : mode_t;
    const S_IWUSR : mode_t;
    const S_IXUSR : mode_t;
  
    const S_IRWXG : mode_t; // RWX mask: group
    const S_IRGRP : mode_t;
    const S_IWGRP : mode_t;
    const S_IXGRP : mode_t;
  
    const S_IRWXO : mode_t; // RWX mask: other
    const S_IROTH : mode_t;
    const S_IWOTH : mode_t;
    const S_IXOTH : mode_t;
  
    const S_ISUID : mode_t; // set user id on execute
    const S_ISGID : mode_t; // set group id on execute
    const S_ISVXT : mode_t; // sticky bit
    val access_mask = S_IXOTH \| S_IXGRP \| S_IXUSR;
  
  
    fun raw_mode: &stat_t -> mode_t = "$1->st_mode";
    fun file_type(m:mode_t)=>m \& S_IFMT;
    fun file_perm(m:mode_t)=>m \& ~S_IFMT;
  
    ctor uint: mode_t = "(unsigned int)$1";
  
  
  
    inherit FileStat_class[Posix, stat_t, mode_t];
    instance FileStat_class[Posix, stat_t, mode_t]
    {
      proc stat: string * &stat_t * &int = "*$3=stat($1.c_str(),$2);";
  
      proc utime: string * double * double * &int =
      """
        {
        utimbuf u;
        u.actime=(time_t)$2;
        u.modtime=(time_t)$3;
        *$4 = utime($1.c_str(),&u);
        }
      """
  
      requires Posix_headers::utime_h;
  
      gen chmod: string * mode_t -> int = "chmod($1.c_str(),$2)" requires Posix_headers::sys_stat_h;
      gen umask: mode_t -> mode_t = "umask($1)";
  
      fun file_type (s:&stat_t): file_type_t =>
        let m = file_type$ raw_mode s in
        if m == S_IFIFO then PIPE
        elif m == S_IFCHR then STREAM
        elif m == S_IFDIR then DIRECTORY
        elif m == S_IFBLK then BLOCK
        elif m == S_IFREG then REGULAR
        elif m == S_IFLNK then SYMLINK
        elif m == S_IFSOCK then SOCKET
        else INDETERMINATE
        endif
      ;
  
    } // instance
  }