9PFILE(2)9PFILE(2)
NAME
Tree, alloctree, freetree,
File, createfile, closefile, removefile, walkfile,
opendirfile, readdirfile, closedirfile, hasperm – in-memory file hierarchy
SYNOPSIS
#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
typedef struct File
{
Ref;
Dir;
void *aux;
...
} 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, long o)
void closedirfile(Readdir *rdir)
int hasperm(File *file, char *uid, int p)
DESCRIPTION
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 inherited 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 single 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 reference.
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
Readdir.
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
implementation to provide more complex groups.
EXAMPLE
The following code correctly handles references
when elementwise walking a path and creating a file.
f = tree->root;
incref(f);
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);
closefile(f);
return nf;
SOURCE
/sys/src/lib9p/file.c
SEE
9p(2)
BUGS
The reference counting is cumbersome.