|  | .TH 9P-FILE 3 | 
|  | .SH NAME | 
|  | Tree, alloctree, freetree, | 
|  | File, createfile, closefile, removefile, walkfile, | 
|  | opendirfile, readdirfile, closedirfile, hasperm \- in-memory file hierarchy | 
|  | .SH SYNOPSIS | 
|  | .ft L | 
|  | .nf | 
|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <fcall.h> | 
|  | #include <thread.h> | 
|  | #include <9p.h> | 
|  | .fi | 
|  | .PP | 
|  | .ft L | 
|  | .nf | 
|  | .ta \w'\fLFile 'u | 
|  | typedef struct File | 
|  | { | 
|  | Ref; | 
|  | Dir; | 
|  | void	*aux; | 
|  | \fI...\fP | 
|  | } File; | 
|  | .fi | 
|  | .PP | 
|  | .ft L | 
|  | .nf | 
|  | .ta \w'\fLTree 'u | 
|  | typedef struct Tree | 
|  | { | 
|  | File *root; | 
|  | \fI...\fP | 
|  | } Tree; | 
|  | .fi | 
|  | .PP | 
|  | .ft L | 
|  | .nf | 
|  | .ta \w'\fLReaddir* 'u +4n +4n | 
|  | 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, char *buf, long n) | 
|  | void	closedirfile(Readdir *rdir) | 
|  | int	hasperm(File *file, char *uid, int p) | 
|  | .fi | 
|  | .SH DESCRIPTION | 
|  | .BR File s | 
|  | and | 
|  | .BR Tree s | 
|  | provide an in-memory file hierarchy | 
|  | intended for use in 9P file servers. | 
|  | .PP | 
|  | .I Alloctree | 
|  | creates a new tree of files, and | 
|  | .I freetree | 
|  | destroys it. | 
|  | The root of the tree | 
|  | (also the | 
|  | .B root | 
|  | element in the structure) | 
|  | will have mode | 
|  | .I mode | 
|  | and be owned by user | 
|  | .I uid | 
|  | and group | 
|  | .IR gid . | 
|  | .I Destroy | 
|  | is used when freeing | 
|  | .B File | 
|  | structures and is described later. | 
|  | .PP | 
|  | .BR File s | 
|  | (including directories) | 
|  | other than the root are created using | 
|  | .IR createfile , | 
|  | which attempts to create a file named | 
|  | .I name | 
|  | in the directory | 
|  | .IR dir . | 
|  | If created, the file will have owner | 
|  | .I uid | 
|  | and have a group inherited from | 
|  | the directory. | 
|  | .I Mode | 
|  | and the permissions of | 
|  | .I dir | 
|  | are used to calculate the permission bits for | 
|  | the file as described in | 
|  | .IR open (9p). | 
|  | It is permissible for | 
|  | .I name | 
|  | to be a slash-separated path rather than a single element. | 
|  | .PP | 
|  | .I 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. | 
|  | .I Removefile | 
|  | returns zero on success, \-1 on error. | 
|  | It is correct to consider | 
|  | .I removefile | 
|  | to be | 
|  | .I closefile | 
|  | with the side effect of removing the file | 
|  | when possible. | 
|  | .PP | 
|  | .I Walkfile | 
|  | evaluates | 
|  | .I path | 
|  | relative to the directory | 
|  | .IR dir , | 
|  | returning the resulting file, | 
|  | or zero if the named file or any intermediate element | 
|  | does not exist. | 
|  | .PP | 
|  | The | 
|  | .B File | 
|  | structure's | 
|  | .B aux | 
|  | pointer may be used by the client | 
|  | for | 
|  | .RB per- File | 
|  | storage. | 
|  | .BR File s | 
|  | are reference-counted: if not zero, | 
|  | .I destroy | 
|  | (specified in the call to | 
|  | .IR alloctree ) | 
|  | will be called for each file when its | 
|  | last reference is removed or when the tree is freed. | 
|  | .I Destroy | 
|  | should take care of any necessary cleanup related to | 
|  | .BR aux . | 
|  | When creating new file references by copying pointers, | 
|  | call | 
|  | .I incref | 
|  | (see | 
|  | .IR lock (3)) | 
|  | to update the reference count. | 
|  | To note the removal of a reference to a file, call | 
|  | .IR closefile . | 
|  | .I Createfile | 
|  | and | 
|  | .I walkfile | 
|  | return new references. | 
|  | .IR Removefile , | 
|  | .IR closefile , | 
|  | and | 
|  | .I walkfile | 
|  | (but not | 
|  | .IR createfile ) | 
|  | consume the passed reference. | 
|  | .PP | 
|  | Directories may be read, yielding a directory entry structure | 
|  | (see | 
|  | .IR stat (9p)) | 
|  | for each file in the directory. | 
|  | In order to allow concurrent reading of directories, | 
|  | clients must obtain a | 
|  | .B Readdir | 
|  | structure by calling | 
|  | .I opendirfile | 
|  | on a directory. | 
|  | Subsequent calls to | 
|  | .I readdirfile | 
|  | will each yield an integral number of machine-independent | 
|  | stat buffers, until end of directory. | 
|  | When finished, call | 
|  | .I closedirfile | 
|  | to free the | 
|  | .BR Readdir . | 
|  | .PP | 
|  | .I Hasperm | 
|  | does simplistic permission checking; it assumes only | 
|  | one-user groups named by uid and returns non-zero if | 
|  | .I uid | 
|  | has permission | 
|  | .I p | 
|  | (a bitwise-or of | 
|  | .BR AREAD , | 
|  | .BR AWRITE | 
|  | and | 
|  | .BR AEXEC ) | 
|  | according to | 
|  | .IB file ->mode \fR. | 
|  | 9P servers written using | 
|  | .B File | 
|  | trees will do standard permission checks automatically; | 
|  | .I hasperm | 
|  | may be called explicitly to do additional checks. | 
|  | A 9P server may link against a different | 
|  | .I hasperm | 
|  | implementation to provide more complex groups. | 
|  | .SH EXAMPLE | 
|  | The following code correctly handles references | 
|  | when elementwise walking a path and creating a file. | 
|  | .IP | 
|  | .EX | 
|  | 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; | 
|  | .EE | 
|  | .SH SOURCE | 
|  | .B \*9/src/lib9p/file.c | 
|  | .SH SEE ALSO | 
|  | .IR 9p (3) | 
|  | .SH BUGS | 
|  | The reference counting is cumbersome. |