#line 981 "/home/travis/build/felix-lang/felix/src/packages/filesystem.fdoc"
  
  class PosixDirectory
  {
    // Posix specific stuff.
    type dirent_t = "struct dirent*" requires Posix_headers::dirent_h;
    type DIR_t = "DIR*" requires Posix_headers::dirent_h;
    proc opendir: string * &DIR_t = "*$2=opendir($1.c_str());";
    fun isNULL: DIR_t -> bool = "$1==0";
    fun isNULL: dirent_t -> bool = "$1==0";
    proc readdir: DIR_t * dirent_t * &dirent_t * &int = "*$4=readdir_r($1, $2, $3);";
    proc closedir: DIR_t = "closedir($1);";
    fun filename: dirent_t -> string = "std::string($1->d_name)";
    private fun getcwd: +char * size -> +char = "getcwd($1,$2)" requires Posix_headers::unistd_h;
  
    // inherit generic stuff
    inherit Directory_class[Posix, PosixFileStat::mode_t];
  
    // instantiate generic stuff
    instance Directory_class[Posix, PosixFileStat::mode_t] {
      gen mkdir: string * PosixFileStat::mode_t -> int = "mkdir($1.c_str(), $2)" requires Posix_headers::sys_stat_h;
      gen mkdir: string  -> int = "mkdir($1.c_str(), 0777)" requires Posix_headers::sys_stat_h;
      proc mkdirs (s:string)
      {
        if s == "" or s == "." or s == ".." or s == "/" do
           return;
        done
        mkdirs$ Filename::dirname s;
        C_hack::ignore$ mkdir s;
      }
  
      // Delete an empty directory.
      gen unlink_empty_dir : string -> int = "rmdir ($1.c_str())" requires Posix_headers::unistd_h;
  
  
      fun getcwd():string = {
        var b: array[char,1024];
        var p = getcwd((&b).stl_begin,size 1024);
        return if C_hack::isNULL p then "" else string p endif;
      }
      fun mk_absolute_filename(s:string) =>
         if PosixFilename::is_absolute_filename s then s else
         #getcwd + "/" + s
      ;
      fun filesin(dname:string): opt[List::list[string]] = {
        //println$ "filesin " + dname;
        var d:DIR_t;
        var e: dirent_t = C_hack::cast[dirent_t]$ C_hack::malloc 5000;
        var eret = e;
        var err:int = 0;
        var files = List::Empty[string];
        opendir(dname,&d);
        if isNULL d do
          println "Error opening dir";
          C_hack::free$ C_hack::cast[address] e;
          return None[List::list[string]];
        else
        //println$ "Opened dir " + dname;
    next:>
          readdir(d,e,&eret, &err);
          if err != 0 do
            println "Error reading dir"; fflush;
            closedir d;
            C_hack::free$ C_hack::cast[address] e;
            return None[List::list[string]];
          elif isNULL eret do
            //println "End of dir";
            closedir d;
            C_hack::free$ C_hack::cast[address] e;
            return Some files;
          else
            //println "Think we got a file?";
            assert err == 0;
            //println$ "Found a file " + filename e;
            files += filename e;
            goto next;
          done
        done
      }
    }
  }