123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- .TH 9PFILE 2
- .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 (5).
- 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 (2))
- 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 (5))
- 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 /sys/src/lib9p/file.c
- .SH SEE ALSO
- .IR 9p (2)
- .SH BUGS
- The reference counting is cumbersome.
|