term% ls -F
term% cat index.txt
9PFILE(2)                     System Calls Manual                    9PFILE(2)

       Tree,  alloctree,  freetree,  File,  createfile, closefile, removefile,
       walkfile, opendirfile, readdirfile, closedirfile, hasperm  -  in-memory
       file hierarchy

       #include <u.h>
       #include <libc.h>
       #include <fcall.h>
       #include <thread.h>
       #include <9p.h>

       typedef struct File
       } File;

       typedef struct Tree
            File *root;
       } Tree;

       Tree*    alloctree(char *uid, char *gid, ulong mode,
                        void (*destroy)(File*))
       void     freetree(Tree *tree)
       File*    createfile(File *dir, char *name, char *uid,
                        ulong mode, void *aux)
       int      removefile(File *file)
       void     closefile(File *file)
       File*    walkfile(File *dir, char *path)
       Readdir* opendirfile(File *dir)
       long     readdirfile(Readdir *rdir, uchar *buf, long n)
       void     closedirfile(Readdir *rdir)
       int      hasperm(File *file, char *uid, int p)

       Files and Trees provide an in-memory file hierarchy intended for use in
       9P file servers.

       Alloctree creates a new tree of files, and freetree destroys  it.   The
       root  of  the  tree  (also the root element in the structure) will have
       mode mode and be owned by user uid and group gid.  Destroy is used when
       freeing File structures and is described later.

       Files  (including  directories)  other  than the root are created using
       createfile, which attempts to create a file named name in the directory
       dir.   If created, the file will have owner uid and have a group inher‐
       ited from the directory.  Mode and the permissions of dir are  used  to
       calculate the permission bits for the file as described in open(5).  It
       is permissible for name to be a slash-separated path rather than a sin‐
       gle element.

       Removefile  removes  a  file  from the file tree.  The file will not be
       freed until the last reference to it has been removed.  Directories may
       only  be removed when empty.  Removefile returns zero on success, -1 on
       error.  It is correct to consider removefile to be closefile  with  the
       side effect of removing the file when possible.

       Walkfile  evaluates  path  relative to the directory dir, returning the
       resulting file, or zero if the named file or any  intermediate  element
       does not exist.

       The File structure's aux pointer may be used by the client for per-File
       storage.  Files are reference-counted: if not zero, destroy  (specified
       in  the  call  to alloctree) will be called for each file when its last
       reference is removed or when the tree is freed.   Destroy  should  take
       care  of  any necessary cleanup related to aux.  When creating new file
       references by copying pointers, call incref (see lock(2)) to update the
       reference  count.   To  note the removal of a reference to a file, call
       closefile.  Createfile and walkfile return new references.  Removefile,
       closefile,  and walkfile (but not createfile) consume the passed refer‐

       Directories may be read, yielding  a  directory  entry  structure  (see
       stat(5))  for each file in the directory.  In order to allow concurrent
       reading of directories, clients must  obtain  a  Readdir  structure  by
       calling  opendirfile  on  a directory.  Subsequent calls to readdirfile
       will each yield an integral number of machine-independent stat buffers,
       until  end  of directory.  When finished, call closedirfile to free the

       Hasperm does simplistic permission checking; it assumes  only  one-user
       groups  named  by  uid  and returns non-zero if uid has permission p (a
       bitwise-or of AREAD, AWRITE and AEXEC)  according  to  file->mode.   9P
       servers  written  using  File  trees will do standard permission checks
       automatically; hasperm  may  be  called  explicitly  to  do  additional
       checks.   A  9P server may link against a different hasperm implementa‐
       tion to provide more complex groups.

       The following code correctly handles references when elementwise  walk‐
       ing a path and creating a file.

              f = tree->root;
              for(i=0; i<n && f!=nil; i++)
                       f = walkfile(f, elem[i]);
              if(f == nil)
                       return nil;
              nf = createfile(f, "foo", "nls", 0666, nil);
              return nf;



       The reference counting is cumbersome.