Blame


1 cfa37a7b 2004-04-10 devnull .TH 9P 3
2 cfa37a7b 2004-04-10 devnull .SH NAME
3 cfa37a7b 2004-04-10 devnull Srv,
4 cfa37a7b 2004-04-10 devnull dirread9p,
5 cfa37a7b 2004-04-10 devnull emalloc9p,
6 cfa37a7b 2004-04-10 devnull erealloc9p,
7 cfa37a7b 2004-04-10 devnull estrdup9p,
8 cfa37a7b 2004-04-10 devnull postfd,
9 cfa37a7b 2004-04-10 devnull postmountsrv,
10 cfa37a7b 2004-04-10 devnull readbuf,
11 cfa37a7b 2004-04-10 devnull readstr,
12 cfa37a7b 2004-04-10 devnull respond,
13 cfa37a7b 2004-04-10 devnull threadpostmountsrv,
14 cfa37a7b 2004-04-10 devnull srv \- 9P file service
15 cfa37a7b 2004-04-10 devnull .SH SYNOPSIS
16 cfa37a7b 2004-04-10 devnull .ft L
17 cfa37a7b 2004-04-10 devnull .nf
18 cfa37a7b 2004-04-10 devnull #include <u.h>
19 cfa37a7b 2004-04-10 devnull #include <libc.h>
20 cfa37a7b 2004-04-10 devnull #include <fcall.h>
21 cfa37a7b 2004-04-10 devnull #include <thread.h>
22 cfa37a7b 2004-04-10 devnull #include <9p.h>
23 cfa37a7b 2004-04-10 devnull .fi
24 cfa37a7b 2004-04-10 devnull .PP
25 cfa37a7b 2004-04-10 devnull .ft L
26 cfa37a7b 2004-04-10 devnull .nf
27 cfa37a7b 2004-04-10 devnull .ta \w'\fL1234'u +\w'\fLTree* 'u
28 cfa37a7b 2004-04-10 devnull typedef struct Srv {
29 cfa37a7b 2004-04-10 devnull Tree* tree;
30 cfa37a7b 2004-04-10 devnull
31 cfa37a7b 2004-04-10 devnull void (*attach)(Req *r);
32 cfa37a7b 2004-04-10 devnull void (*auth)(Req *r);
33 cfa37a7b 2004-04-10 devnull void (*open)(Req *r);
34 cfa37a7b 2004-04-10 devnull void (*create)(Req *r);
35 cfa37a7b 2004-04-10 devnull void (*read)(Req *r);
36 cfa37a7b 2004-04-10 devnull void (*write)(Req *r);
37 cfa37a7b 2004-04-10 devnull void (*remove)(Req *r);
38 cfa37a7b 2004-04-10 devnull void (*flush)(Req *r);
39 cfa37a7b 2004-04-10 devnull void (*stat)(Req *r);
40 cfa37a7b 2004-04-10 devnull void (*wstat)(Req *r);
41 cfa37a7b 2004-04-10 devnull void (*walk)(Req *r);
42 cfa37a7b 2004-04-10 devnull
43 cfa37a7b 2004-04-10 devnull char* (*walk1)(Fid *fid, char *name, Qid *qid);
44 cfa37a7b 2004-04-10 devnull char* (*clone)(Fid *oldfid, Fid *newfid);
45 cfa37a7b 2004-04-10 devnull
46 cfa37a7b 2004-04-10 devnull void (*destroyfid)(Fid *fid);
47 cfa37a7b 2004-04-10 devnull void (*destroyreq)(Req *r);
48 cfa37a7b 2004-04-10 devnull void (*end)(Srv *s);
49 cfa37a7b 2004-04-10 devnull void* aux;
50 cfa37a7b 2004-04-10 devnull
51 cfa37a7b 2004-04-10 devnull int infd;
52 cfa37a7b 2004-04-10 devnull int outfd;
53 cfa37a7b 2004-04-10 devnull int srvfd;
54 cfa37a7b 2004-04-10 devnull int nopipe;
55 cfa37a7b 2004-04-10 devnull } Srv;
56 cfa37a7b 2004-04-10 devnull .fi
57 cfa37a7b 2004-04-10 devnull .PP
58 cfa37a7b 2004-04-10 devnull .nf
59 cfa37a7b 2004-04-10 devnull .ft L
60 cfa37a7b 2004-04-10 devnull .ta \w'\fLvoid* 'u
61 cfa37a7b 2004-04-10 devnull int srv(Srv *s)
62 cfa37a7b 2004-04-10 devnull void postmountsrv(Srv *s, char *name, char *mtpt, int flag)
63 cfa37a7b 2004-04-10 devnull void threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag)
64 cfa37a7b 2004-04-10 devnull int postfd(char *srvname, int fd)
65 cfa37a7b 2004-04-10 devnull void respond(Req *r, char *error)
66 cfa37a7b 2004-04-10 devnull ulong readstr(Req *r, char *src)
67 cfa37a7b 2004-04-10 devnull ulong readbuf(Req *r, void *src, ulong nsrc)
68 cfa37a7b 2004-04-10 devnull typedef int Dirgen(int n, Dir *dir, void *aux)
69 cfa37a7b 2004-04-10 devnull void dirread9p(Req *r, Dirgen *gen, void *aux)
70 cfa37a7b 2004-04-10 devnull void walkandclone(Req *r, char *(*walk1)(Fid *old, char *name, void *v),
71 cfa37a7b 2004-04-10 devnull char *(*clone)(Fid *old, Fid *new, void *v), void *v)
72 cfa37a7b 2004-04-10 devnull .fi
73 cfa37a7b 2004-04-10 devnull .PP
74 cfa37a7b 2004-04-10 devnull .nf
75 cfa37a7b 2004-04-10 devnull .ft L
76 cfa37a7b 2004-04-10 devnull .ta \w'\fLvoid* 'u
77 cfa37a7b 2004-04-10 devnull void* emalloc9p(ulong n)
78 cfa37a7b 2004-04-10 devnull void* erealloc9p(void *v, ulong n)
79 cfa37a7b 2004-04-10 devnull char* estrdup9p(char *s)
80 cfa37a7b 2004-04-10 devnull .fi
81 cfa37a7b 2004-04-10 devnull .PP
82 cfa37a7b 2004-04-10 devnull .nf
83 cfa37a7b 2004-04-10 devnull .ft L
84 cfa37a7b 2004-04-10 devnull extern int chatty9p;
85 cfa37a7b 2004-04-10 devnull .fi
86 cfa37a7b 2004-04-10 devnull .SH DESCRIPTION
87 cfa37a7b 2004-04-10 devnull The function
88 cfa37a7b 2004-04-10 devnull .I srv
89 cfa37a7b 2004-04-10 devnull serves a 9P session by reading requests from
90 cfa37a7b 2004-04-10 devnull .BR s->infd ,
91 cfa37a7b 2004-04-10 devnull dispatching them to the function pointers kept in
92 cfa37a7b 2004-04-10 devnull .BR Srv ,
93 cfa37a7b 2004-04-10 devnull and
94 cfa37a7b 2004-04-10 devnull writing the responses to
95 cfa37a7b 2004-04-10 devnull .BR s->outfd .
96 cfa37a7b 2004-04-10 devnull (Typically,
97 cfa37a7b 2004-04-10 devnull .I postmountsrv
98 cfa37a7b 2004-04-10 devnull or
99 cfa37a7b 2004-04-10 devnull .I threadpostmountsrv
100 cfa37a7b 2004-04-10 devnull initializes the
101 cfa37a7b 2004-04-10 devnull .B infd
102 cfa37a7b 2004-04-10 devnull and
103 cfa37a7b 2004-04-10 devnull .B outfd
104 cfa37a7b 2004-04-10 devnull structure members. See the description below.)
105 cfa37a7b 2004-04-10 devnull .PP
106 cfa37a7b 2004-04-10 devnull .B Req
107 cfa37a7b 2004-04-10 devnull and
108 cfa37a7b 2004-04-10 devnull .B Fid
109 cfa37a7b 2004-04-10 devnull structures are allocated one-to-one with uncompleted
110 cfa37a7b 2004-04-10 devnull requests and active fids, and are described in
111 bf8a59fa 2004-04-11 devnull .IR 9pfid (3).
112 cfa37a7b 2004-04-10 devnull .PP
113 cfa37a7b 2004-04-10 devnull The behavior of
114 cfa37a7b 2004-04-10 devnull .I srv
115 cfa37a7b 2004-04-10 devnull depends on whether there is a file tree
116 cfa37a7b 2004-04-10 devnull (see
117 bf8a59fa 2004-04-11 devnull .IR 9pfile (3))
118 cfa37a7b 2004-04-10 devnull associated with the server, that is,
119 cfa37a7b 2004-04-10 devnull whether the
120 cfa37a7b 2004-04-10 devnull .B tree
121 cfa37a7b 2004-04-10 devnull element is nonzero.
122 cfa37a7b 2004-04-10 devnull The differences are made explicit in the
123 cfa37a7b 2004-04-10 devnull discussion of the service loop below.
124 cfa37a7b 2004-04-10 devnull The
125 cfa37a7b 2004-04-10 devnull .B aux
126 cfa37a7b 2004-04-10 devnull element is the client's, to do with as it pleases.
127 cfa37a7b 2004-04-10 devnull .PP
128 cfa37a7b 2004-04-10 devnull .I Srv
129 cfa37a7b 2004-04-10 devnull does not return until the 9P conversation is finished.
130 cfa37a7b 2004-04-10 devnull Since it is usually run in a separate process so that
131 cfa37a7b 2004-04-10 devnull the caller can exit, the service loop has little chance
132 cfa37a7b 2004-04-10 devnull to return gracefully on out of memory errors.
133 cfa37a7b 2004-04-10 devnull It calls
134 cfa37a7b 2004-04-10 devnull .IR emalloc9p ,
135 cfa37a7b 2004-04-10 devnull .IR erealloc9p ,
136 cfa37a7b 2004-04-10 devnull and
137 cfa37a7b 2004-04-10 devnull .I estrdup9p
138 cfa37a7b 2004-04-10 devnull to obtain its memory.
139 cfa37a7b 2004-04-10 devnull The default implementations of these functions
140 cfa37a7b 2004-04-10 devnull act as
141 cfa37a7b 2004-04-10 devnull .IR malloc ,
142 cfa37a7b 2004-04-10 devnull .IR realloc ,
143 cfa37a7b 2004-04-10 devnull and
144 cfa37a7b 2004-04-10 devnull .I strdup
145 cfa37a7b 2004-04-10 devnull but abort the program if they run out of memory.
146 cfa37a7b 2004-04-10 devnull If alternate behavior is desired, clients can link against
147 cfa37a7b 2004-04-10 devnull alternate implementations of these functions.
148 cfa37a7b 2004-04-10 devnull .PP
149 cfa37a7b 2004-04-10 devnull .I Postmountsrv
150 cfa37a7b 2004-04-10 devnull and
151 cfa37a7b 2004-04-10 devnull .I threadpostmountsrv
152 cfa37a7b 2004-04-10 devnull are wrappers that create a separate process in which to run
153 cfa37a7b 2004-04-10 devnull .IR srv .
154 cfa37a7b 2004-04-10 devnull They do the following:
155 cfa37a7b 2004-04-10 devnull .IP
156 cfa37a7b 2004-04-10 devnull If
157 cfa37a7b 2004-04-10 devnull .IB s -> nopipe
158 cfa37a7b 2004-04-10 devnull is zero (the common case),
159 cfa37a7b 2004-04-10 devnull initialize
160 cfa37a7b 2004-04-10 devnull .IB s -> infd
161 cfa37a7b 2004-04-10 devnull and
162 cfa37a7b 2004-04-10 devnull .IB s -> outfd
163 cfa37a7b 2004-04-10 devnull to be one end of a freshly allocated pipe,
164 cfa37a7b 2004-04-10 devnull with
165 cfa37a7b 2004-04-10 devnull .IB s -> srvfd
166 cfa37a7b 2004-04-10 devnull initialized as the other end.
167 cfa37a7b 2004-04-10 devnull .IP
168 cfa37a7b 2004-04-10 devnull If
169 cfa37a7b 2004-04-10 devnull .B name
170 cfa37a7b 2004-04-10 devnull is non-nil, call
171 cfa37a7b 2004-04-10 devnull .BI postfd( s -> srvfd ,
172 cfa37a7b 2004-04-10 devnull .IB name )
173 cfa37a7b 2004-04-10 devnull to post
174 cfa37a7b 2004-04-10 devnull .IB s -> srvfd
175 cfa37a7b 2004-04-10 devnull as
176 cfa37a7b 2004-04-10 devnull .BI /srv/ name .
177 cfa37a7b 2004-04-10 devnull .IP
178 cfa37a7b 2004-04-10 devnull Fork a child process via
179 cfa37a7b 2004-04-10 devnull .I rfork
180 cfa37a7b 2004-04-10 devnull (see
181 bf8a59fa 2004-04-11 devnull .IR fork (3))
182 cfa37a7b 2004-04-10 devnull or
183 cfa37a7b 2004-04-10 devnull .I procrfork
184 cfa37a7b 2004-04-10 devnull (see
185 bf8a59fa 2004-04-11 devnull .IR thread (3)),
186 cfa37a7b 2004-04-10 devnull using the
187 cfa37a7b 2004-04-10 devnull .BR RFFDG ,
188 cfa37a7b 2004-04-10 devnull .RR RFNOTEG ,
189 cfa37a7b 2004-04-10 devnull .BR RFNAMEG ,
190 cfa37a7b 2004-04-10 devnull and
191 cfa37a7b 2004-04-10 devnull .BR RFMEM
192 cfa37a7b 2004-04-10 devnull flags.
193 cfa37a7b 2004-04-10 devnull The child process
194 cfa37a7b 2004-04-10 devnull calls
195 cfa37a7b 2004-04-10 devnull .IB close( s -> srvfd )
196 cfa37a7b 2004-04-10 devnull and then
197 cfa37a7b 2004-04-10 devnull .IB srv( s ) \fR;
198 cfa37a7b 2004-04-10 devnull it will exit once
199 cfa37a7b 2004-04-10 devnull .I srv
200 cfa37a7b 2004-04-10 devnull returns.
201 cfa37a7b 2004-04-10 devnull .IP
202 cfa37a7b 2004-04-10 devnull If
203 cfa37a7b 2004-04-10 devnull .I mtpt
204 cfa37a7b 2004-04-10 devnull is non-nil,
205 cfa37a7b 2004-04-10 devnull call
206 cfa37a7b 2004-04-10 devnull .BI amount( s -> srvfd,
207 cfa37a7b 2004-04-10 devnull .IB mtpt ,
208 cfa37a7b 2004-04-10 devnull .IB flag ,
209 cfa37a7b 2004-04-10 devnull \fB"")\fR;
210 cfa37a7b 2004-04-10 devnull otherwise, close
211 cfa37a7b 2004-04-10 devnull .IB s -> srvfd \fR.
212 cfa37a7b 2004-04-10 devnull .IP
213 cfa37a7b 2004-04-10 devnull The parent returns to the caller.
214 cfa37a7b 2004-04-10 devnull .LP
215 cfa37a7b 2004-04-10 devnull If any error occurs during
216 cfa37a7b 2004-04-10 devnull this process, the entire process is terminated by calling
217 cfa37a7b 2004-04-10 devnull .I sysfatal
218 cfa37a7b 2004-04-10 devnull (see
219 bf8a59fa 2004-04-11 devnull .IR perror (3)).
220 cfa37a7b 2004-04-10 devnull .SS Service functions
221 cfa37a7b 2004-04-10 devnull The functions in a
222 cfa37a7b 2004-04-10 devnull .B Srv
223 cfa37a7b 2004-04-10 devnull structure named after 9P transactions
224 cfa37a7b 2004-04-10 devnull are called to satisfy requests as they arrive.
225 cfa37a7b 2004-04-10 devnull If a function is provided, it
226 cfa37a7b 2004-04-10 devnull .I must
227 cfa37a7b 2004-04-10 devnull arrange for
228 cfa37a7b 2004-04-10 devnull .I respond
229 cfa37a7b 2004-04-10 devnull to be called when the request is satisfied.
230 cfa37a7b 2004-04-10 devnull The only parameter of each service function
231 cfa37a7b 2004-04-10 devnull is a
232 cfa37a7b 2004-04-10 devnull .B Req*
233 cfa37a7b 2004-04-10 devnull parameter (say
234 cfa37a7b 2004-04-10 devnull .IR r ).
235 cfa37a7b 2004-04-10 devnull The incoming request parameters are stored in
236 cfa37a7b 2004-04-10 devnull .IB r -> ifcall \fR;
237 cfa37a7b 2004-04-10 devnull .IB r -> fid
238 cfa37a7b 2004-04-10 devnull and
239 cfa37a7b 2004-04-10 devnull .IB r -> newfid
240 cfa37a7b 2004-04-10 devnull are pointers to
241 cfa37a7b 2004-04-10 devnull .B Fid
242 cfa37a7b 2004-04-10 devnull structures corresponding to the
243 cfa37a7b 2004-04-10 devnull numeric fids in
244 cfa37a7b 2004-04-10 devnull .IB r -> ifcall \fR;
245 cfa37a7b 2004-04-10 devnull similarly,
246 cfa37a7b 2004-04-10 devnull .IB r -> oldreq
247 cfa37a7b 2004-04-10 devnull is the
248 cfa37a7b 2004-04-10 devnull .B Req
249 cfa37a7b 2004-04-10 devnull structure corresponding to
250 cfa37a7b 2004-04-10 devnull .IB r -> ifcall.oldtag \fR.
251 cfa37a7b 2004-04-10 devnull The outgoing response data should be stored in
252 cfa37a7b 2004-04-10 devnull .IB r -> ofcall \fR.
253 cfa37a7b 2004-04-10 devnull The one exception to this rule is that
254 cfa37a7b 2004-04-10 devnull .I stat
255 cfa37a7b 2004-04-10 devnull should fill in
256 cfa37a7b 2004-04-10 devnull .IB r -> d
257 cfa37a7b 2004-04-10 devnull rather than
258 cfa37a7b 2004-04-10 devnull .IB r -> ofcall.stat \fR:
259 cfa37a7b 2004-04-10 devnull the library will convert the structure into the machine-independent
260 cfa37a7b 2004-04-10 devnull wire representation.
261 cfa37a7b 2004-04-10 devnull Similarly,
262 cfa37a7b 2004-04-10 devnull .I wstat
263 cfa37a7b 2004-04-10 devnull may consult
264 cfa37a7b 2004-04-10 devnull .IB r -> d
265 cfa37a7b 2004-04-10 devnull rather than decoding
266 cfa37a7b 2004-04-10 devnull .IB r -> ifcall . stat
267 cfa37a7b 2004-04-10 devnull itself.
268 cfa37a7b 2004-04-10 devnull When a request has been handled,
269 cfa37a7b 2004-04-10 devnull .I respond
270 cfa37a7b 2004-04-10 devnull should be called with
271 cfa37a7b 2004-04-10 devnull .I r
272 cfa37a7b 2004-04-10 devnull and an error string.
273 cfa37a7b 2004-04-10 devnull If the request was satisfied successfully, the error
274 cfa37a7b 2004-04-10 devnull string should be a nil pointer.
275 cfa37a7b 2004-04-10 devnull Note that it is permissible for a function to return
276 cfa37a7b 2004-04-10 devnull without itself calling
277 cfa37a7b 2004-04-10 devnull .IR respond ,
278 cfa37a7b 2004-04-10 devnull as long as it has arranged for
279 cfa37a7b 2004-04-10 devnull .I respond
280 cfa37a7b 2004-04-10 devnull to be called at some point in the future
281 cfa37a7b 2004-04-10 devnull by another proc sharing its address space,
282 cfa37a7b 2004-04-10 devnull but see the discussion of
283 cfa37a7b 2004-04-10 devnull .I flush
284 cfa37a7b 2004-04-10 devnull below.
285 cfa37a7b 2004-04-10 devnull Once
286 cfa37a7b 2004-04-10 devnull .I respond
287 cfa37a7b 2004-04-10 devnull has been called, the
288 cfa37a7b 2004-04-10 devnull .B Req*
289 cfa37a7b 2004-04-10 devnull as well as any pointers it once contained must
290 cfa37a7b 2004-04-10 devnull be considered freed and not referenced.
291 cfa37a7b 2004-04-10 devnull .PP
292 cfa37a7b 2004-04-10 devnull If the service loop detects an error in a request
293 cfa37a7b 2004-04-10 devnull (e.g., an attempt to reuse an extant fid, an open of
294 cfa37a7b 2004-04-10 devnull an already open fid, a read from a fid opened for write, etc.)
295 cfa37a7b 2004-04-10 devnull it will reply with an error without consulting
296 cfa37a7b 2004-04-10 devnull the service functions.
297 cfa37a7b 2004-04-10 devnull .PP
298 cfa37a7b 2004-04-10 devnull The service loop provided by
299 cfa37a7b 2004-04-10 devnull .I srv
300 cfa37a7b 2004-04-10 devnull (and indirectly by
301 cfa37a7b 2004-04-10 devnull .I postmountsrv
302 cfa37a7b 2004-04-10 devnull and
303 cfa37a7b 2004-04-10 devnull .IR threadpostmountsrv )
304 cfa37a7b 2004-04-10 devnull is single-threaded.
305 cfa37a7b 2004-04-10 devnull If it is expected that some requests might
306 cfa37a7b 2004-04-10 devnull block, arranging for alternate processes
307 cfa37a7b 2004-04-10 devnull to handle them is suggested.
308 cfa37a7b 2004-04-10 devnull .PP
309 cfa37a7b 2004-04-10 devnull The constraints on the service functions are as follows.
310 cfa37a7b 2004-04-10 devnull These constraints are checked while the server executes.
311 cfa37a7b 2004-04-10 devnull If a service function fails to do something it ought to have,
312 cfa37a7b 2004-04-10 devnull .I srv
313 cfa37a7b 2004-04-10 devnull will call
314 cfa37a7b 2004-04-10 devnull .I endsrv
315 cfa37a7b 2004-04-10 devnull and then abort.
316 cfa37a7b 2004-04-10 devnull .TP
317 cfa37a7b 2004-04-10 devnull .I Auth
318 cfa37a7b 2004-04-10 devnull If authentication is desired,
319 cfa37a7b 2004-04-10 devnull the
320 cfa37a7b 2004-04-10 devnull .I auth
321 cfa37a7b 2004-04-10 devnull function should record that
322 cfa37a7b 2004-04-10 devnull .I afid
323 cfa37a7b 2004-04-10 devnull is the new authentication fid and
324 cfa37a7b 2004-04-10 devnull set
325 cfa37a7b 2004-04-10 devnull .I afid->qid
326 cfa37a7b 2004-04-10 devnull and
327 cfa37a7b 2004-04-10 devnull .IR ofcall.qid .
328 cfa37a7b 2004-04-10 devnull .I Auth
329 cfa37a7b 2004-04-10 devnull may be nil, in which case it will be treated as having
330 cfa37a7b 2004-04-10 devnull responded with the error
331 cfa37a7b 2004-04-10 devnull .RI `` "argv0: authentication not required" ,''
332 cfa37a7b 2004-04-10 devnull where
333 cfa37a7b 2004-04-10 devnull .I argv0
334 cfa37a7b 2004-04-10 devnull is the program name variable as set by
335 cfa37a7b 2004-04-10 devnull .I ARGBEGIN
336 cfa37a7b 2004-04-10 devnull (see
337 bf8a59fa 2004-04-11 devnull .IR arg (3)).
338 cfa37a7b 2004-04-10 devnull .TP
339 cfa37a7b 2004-04-10 devnull .I Attach
340 cfa37a7b 2004-04-10 devnull The
341 cfa37a7b 2004-04-10 devnull .I attach
342 cfa37a7b 2004-04-10 devnull function should check the authentication state of
343 cfa37a7b 2004-04-10 devnull .I afid
344 cfa37a7b 2004-04-10 devnull if desired,
345 cfa37a7b 2004-04-10 devnull and set
346 cfa37a7b 2004-04-10 devnull .IB r -> fid -> qid
347 cfa37a7b 2004-04-10 devnull and
348 cfa37a7b 2004-04-10 devnull .I ofcall.qid
349 cfa37a7b 2004-04-10 devnull to the qid of the file system root.
350 cfa37a7b 2004-04-10 devnull .I Attach
351 cfa37a7b 2004-04-10 devnull may be nil only if file trees are in use;
352 cfa37a7b 2004-04-10 devnull in this case, the qid will be filled from the root
353 cfa37a7b 2004-04-10 devnull of the tree, and no authentication will be done.
354 cfa37a7b 2004-04-10 devnull .TP
355 cfa37a7b 2004-04-10 devnull .I Walk
356 cfa37a7b 2004-04-10 devnull If file trees are in use,
357 cfa37a7b 2004-04-10 devnull .I walk
358 cfa37a7b 2004-04-10 devnull is handled internally, and
359 cfa37a7b 2004-04-10 devnull .IB srv -> walk
360 cfa37a7b 2004-04-10 devnull is never called.
361 cfa37a7b 2004-04-10 devnull .IP
362 cfa37a7b 2004-04-10 devnull If file trees are not in use,
363 cfa37a7b 2004-04-10 devnull .I walk
364 cfa37a7b 2004-04-10 devnull should consult
365 cfa37a7b 2004-04-10 devnull .IB r -> ifcall . wname
366 cfa37a7b 2004-04-10 devnull and
367 cfa37a7b 2004-04-10 devnull .IB r -> ifcall . nwname \fR,
368 cfa37a7b 2004-04-10 devnull filling in
369 cfa37a7b 2004-04-10 devnull .IB ofcall . qid
370 cfa37a7b 2004-04-10 devnull and
371 cfa37a7b 2004-04-10 devnull .IB ofcall . nqid \fR,
372 cfa37a7b 2004-04-10 devnull and also copying any necessary
373 cfa37a7b 2004-04-10 devnull .I aux
374 cfa37a7b 2004-04-10 devnull state from
375 cfa37a7b 2004-04-10 devnull .IB r -> fid
376 cfa37a7b 2004-04-10 devnull to
377 cfa37a7b 2004-04-10 devnull .IB r -> newfid
378 cfa37a7b 2004-04-10 devnull when the two are different.
379 cfa37a7b 2004-04-10 devnull As long as
380 cfa37a7b 2004-04-10 devnull .I walk
381 cfa37a7b 2004-04-10 devnull sets
382 cfa37a7b 2004-04-10 devnull .IB ofcall . nqid
383 cfa37a7b 2004-04-10 devnull appropriately, it can
384 cfa37a7b 2004-04-10 devnull .I respond
385 cfa37a7b 2004-04-10 devnull with a nil error string even when 9P
386 cfa37a7b 2004-04-10 devnull demands an error
387 cfa37a7b 2004-04-10 devnull .RI ( e.g. ,
388 cfa37a7b 2004-04-10 devnull in the case of a short walk);
389 cfa37a7b 2004-04-10 devnull the library detects error conditions and handles them appropriately.
390 cfa37a7b 2004-04-10 devnull .IP
391 cfa37a7b 2004-04-10 devnull Because implementing the full walk message is intricate and
392 cfa37a7b 2004-04-10 devnull prone to error, the helper routine
393 cfa37a7b 2004-04-10 devnull .I walkandclone
394 cfa37a7b 2004-04-10 devnull will handle the request given pointers to two functions
395 cfa37a7b 2004-04-10 devnull .I walk1
396 cfa37a7b 2004-04-10 devnull and (optionally)
397 cfa37a7b 2004-04-10 devnull .I clone .
398 cfa37a7b 2004-04-10 devnull .IR Clone ,
399 cfa37a7b 2004-04-10 devnull if non-nil, is called to signal the creation of
400 cfa37a7b 2004-04-10 devnull .I newfid
401 cfa37a7b 2004-04-10 devnull from
402 cfa37a7b 2004-04-10 devnull .IR oldfid .
403 cfa37a7b 2004-04-10 devnull Typically a
404 cfa37a7b 2004-04-10 devnull .I clone
405 cfa37a7b 2004-04-10 devnull routine will copy or increment a reference count in
406 cfa37a7b 2004-04-10 devnull .IR oldfid 's
407 cfa37a7b 2004-04-10 devnull .I aux
408 cfa37a7b 2004-04-10 devnull element.
409 cfa37a7b 2004-04-10 devnull .I Walk1
410 cfa37a7b 2004-04-10 devnull should walk
411 cfa37a7b 2004-04-10 devnull .I fid
412 cfa37a7b 2004-04-10 devnull to
413 cfa37a7b 2004-04-10 devnull .IR name ,
414 cfa37a7b 2004-04-10 devnull initializing
415 cfa37a7b 2004-04-10 devnull .IB fid -> qid
416 cfa37a7b 2004-04-10 devnull to the new path's qid.
417 cfa37a7b 2004-04-10 devnull Both should return nil
418 cfa37a7b 2004-04-10 devnull on success or an error message on error.
419 cfa37a7b 2004-04-10 devnull .I Walkandclone
420 cfa37a7b 2004-04-10 devnull will call
421 cfa37a7b 2004-04-10 devnull .I respond
422 cfa37a7b 2004-04-10 devnull after handling the request.
423 cfa37a7b 2004-04-10 devnull .TP
424 cfa37a7b 2004-04-10 devnull .I Walk1\fR, \fPClone
425 cfa37a7b 2004-04-10 devnull If the client provides functions
426 cfa37a7b 2004-04-10 devnull .IB srv -> walk1
427 cfa37a7b 2004-04-10 devnull and (optionally)
428 cfa37a7b 2004-04-10 devnull .IB srv -> clone \fR,
429 cfa37a7b 2004-04-10 devnull the 9P service loop will call
430 cfa37a7b 2004-04-10 devnull .I walkandclone
431 cfa37a7b 2004-04-10 devnull with these functions to handle the request.
432 cfa37a7b 2004-04-10 devnull Unlike the
433 cfa37a7b 2004-04-10 devnull .I walk1
434 cfa37a7b 2004-04-10 devnull above,
435 cfa37a7b 2004-04-10 devnull .IB srv -> walk1
436 cfa37a7b 2004-04-10 devnull must fill in both
437 cfa37a7b 2004-04-10 devnull .IB fid -> qid
438 cfa37a7b 2004-04-10 devnull and
439 cfa37a7b 2004-04-10 devnull .BI * qid
440 cfa37a7b 2004-04-10 devnull with the new qid on a successful walk.
441 cfa37a7b 2004-04-10 devnull .TP
442 cfa37a7b 2004-04-10 devnull .I Open
443 cfa37a7b 2004-04-10 devnull If file trees are in use, the file
444 cfa37a7b 2004-04-10 devnull metadata will be consulted on open, create, remove, and wstat
445 cfa37a7b 2004-04-10 devnull to see if the requester has the appropriate permissions.
446 cfa37a7b 2004-04-10 devnull If not, an error will be sent back without consulting a service function.
447 cfa37a7b 2004-04-10 devnull .PP
448 cfa37a7b 2004-04-10 devnull If not using file trees or the user has the appropriate permissions,
449 cfa37a7b 2004-04-10 devnull .I open
450 cfa37a7b 2004-04-10 devnull is called with
451 cfa37a7b 2004-04-10 devnull .IB r -> ofcall . qid
452 cfa37a7b 2004-04-10 devnull already initialized to the one stored in the
453 cfa37a7b 2004-04-10 devnull .B Fid
454 cfa37a7b 2004-04-10 devnull structure (that is, the one returned in the previous walk).
455 cfa37a7b 2004-04-10 devnull If the qid changes, both should be updated.
456 cfa37a7b 2004-04-10 devnull .TP
457 cfa37a7b 2004-04-10 devnull .I Create
458 cfa37a7b 2004-04-10 devnull The
459 cfa37a7b 2004-04-10 devnull .I create
460 cfa37a7b 2004-04-10 devnull function must fill in
461 cfa37a7b 2004-04-10 devnull both
462 cfa37a7b 2004-04-10 devnull .IB r -> fid -> qid
463 cfa37a7b 2004-04-10 devnull and
464 cfa37a7b 2004-04-10 devnull .IB r -> ofcall . qid
465 cfa37a7b 2004-04-10 devnull on success.
466 cfa37a7b 2004-04-10 devnull When using file trees,
467 cfa37a7b 2004-04-10 devnull .I create
468 cfa37a7b 2004-04-10 devnull should allocate a new
469 cfa37a7b 2004-04-10 devnull .B File
470 cfa37a7b 2004-04-10 devnull with
471 cfa37a7b 2004-04-10 devnull .IR createfile ;
472 cfa37a7b 2004-04-10 devnull note that
473 cfa37a7b 2004-04-10 devnull .I createfile
474 cfa37a7b 2004-04-10 devnull may return nil (because, say, the file already exists).
475 cfa37a7b 2004-04-10 devnull If the
476 cfa37a7b 2004-04-10 devnull .I create
477 cfa37a7b 2004-04-10 devnull function is nil,
478 cfa37a7b 2004-04-10 devnull .I srv
479 cfa37a7b 2004-04-10 devnull behaves as though it were a function that always responded
480 cfa37a7b 2004-04-10 devnull with the error ``create prohibited''.
481 cfa37a7b 2004-04-10 devnull .TP
482 cfa37a7b 2004-04-10 devnull .I Remove
483 cfa37a7b 2004-04-10 devnull .I Remove
484 cfa37a7b 2004-04-10 devnull should mark the file as removed, whether
485 cfa37a7b 2004-04-10 devnull by calling
486 cfa37a7b 2004-04-10 devnull .I removefile
487 cfa37a7b 2004-04-10 devnull when using file trees, or by updating an internal data structure.
488 cfa37a7b 2004-04-10 devnull In general it is not a good idea to clean up the
489 cfa37a7b 2004-04-10 devnull .I aux
490 cfa37a7b 2004-04-10 devnull information associated with the corresponding
491 cfa37a7b 2004-04-10 devnull .B File
492 cfa37a7b 2004-04-10 devnull at this time, to avoid memory errors if other
493 cfa37a7b 2004-04-10 devnull fids have references to that file.
494 cfa37a7b 2004-04-10 devnull Instead, it is suggested that
495 cfa37a7b 2004-04-10 devnull .I remove
496 cfa37a7b 2004-04-10 devnull simply mark the file as removed (so that further
497 cfa37a7b 2004-04-10 devnull operations on it know to fail) and wait until the
498 cfa37a7b 2004-04-10 devnull file tree's destroy function is called to reclaim the
499 cfa37a7b 2004-04-10 devnull .I aux
500 cfa37a7b 2004-04-10 devnull pointer.
501 cfa37a7b 2004-04-10 devnull If not using file trees, it is prudent to take the
502 cfa37a7b 2004-04-10 devnull analogous measures.
503 cfa37a7b 2004-04-10 devnull If
504 cfa37a7b 2004-04-10 devnull .I remove
505 cfa37a7b 2004-04-10 devnull is not provided, all remove requests will draw
506 cfa37a7b 2004-04-10 devnull ``remove prohibited'' errors.
507 cfa37a7b 2004-04-10 devnull .TP
508 cfa37a7b 2004-04-10 devnull .I Read
509 cfa37a7b 2004-04-10 devnull The
510 cfa37a7b 2004-04-10 devnull .I read
511 cfa37a7b 2004-04-10 devnull function must be provided; it fills
512 cfa37a7b 2004-04-10 devnull .IB r -> ofcall . data
513 cfa37a7b 2004-04-10 devnull with at most
514 cfa37a7b 2004-04-10 devnull .IB r -> ifcall . count
515 cfa37a7b 2004-04-10 devnull bytes of data from offset
516 cfa37a7b 2004-04-10 devnull .IB r -> ifcall . offset
517 cfa37a7b 2004-04-10 devnull of the file.
518 cfa37a7b 2004-04-10 devnull It also sets
519 cfa37a7b 2004-04-10 devnull .IB r -> ofcall . count
520 cfa37a7b 2004-04-10 devnull to the number of bytes being returned.
521 cfa37a7b 2004-04-10 devnull If using file trees,
522 cfa37a7b 2004-04-10 devnull .I srv
523 cfa37a7b 2004-04-10 devnull will handle reads of directories internally, only
524 cfa37a7b 2004-04-10 devnull calling
525 cfa37a7b 2004-04-10 devnull .I read
526 cfa37a7b 2004-04-10 devnull for requests on files.
527 cfa37a7b 2004-04-10 devnull .I Readstr
528 cfa37a7b 2004-04-10 devnull and
529 cfa37a7b 2004-04-10 devnull .I readbuf
530 cfa37a7b 2004-04-10 devnull are useful for satisfying read requests on a string or buffer.
531 cfa37a7b 2004-04-10 devnull Consulting the request in
532 cfa37a7b 2004-04-10 devnull .IB r -> ifcall \fR,
533 cfa37a7b 2004-04-10 devnull they fill
534 cfa37a7b 2004-04-10 devnull .IB r -> ofcall . data
535 cfa37a7b 2004-04-10 devnull and set
536 cfa37a7b 2004-04-10 devnull .IB r -> ofcall . count \fR;
537 cfa37a7b 2004-04-10 devnull they do not call
538 cfa37a7b 2004-04-10 devnull .IB respond .
539 cfa37a7b 2004-04-10 devnull Similarly,
540 cfa37a7b 2004-04-10 devnull .I dirread9p
541 cfa37a7b 2004-04-10 devnull can be used to handle directory reads in servers
542 cfa37a7b 2004-04-10 devnull not using file trees.
543 cfa37a7b 2004-04-10 devnull The passed
544 cfa37a7b 2004-04-10 devnull .I gen
545 cfa37a7b 2004-04-10 devnull function will be called as necessary to
546 cfa37a7b 2004-04-10 devnull fill
547 cfa37a7b 2004-04-10 devnull .I dir
548 cfa37a7b 2004-04-10 devnull with information for the
549 cfa37a7b 2004-04-10 devnull .IR n th
550 cfa37a7b 2004-04-10 devnull entry in the directory.
551 cfa37a7b 2004-04-10 devnull The string pointers placed in
552 cfa37a7b 2004-04-10 devnull .I dir
553 cfa37a7b 2004-04-10 devnull should be fresh copies
554 cfa37a7b 2004-04-10 devnull made with
555 cfa37a7b 2004-04-10 devnull .IR estrdup9p ;
556 cfa37a7b 2004-04-10 devnull they will be freed by
557 cfa37a7b 2004-04-10 devnull .I dirread9p
558 cfa37a7b 2004-04-10 devnull after each successful call to
559 cfa37a7b 2004-04-10 devnull .IR gen .
560 cfa37a7b 2004-04-10 devnull .I Gen
561 cfa37a7b 2004-04-10 devnull should return zero if it successfully filled
562 cfa37a7b 2004-04-10 devnull .IR dir ,
563 cfa37a7b 2004-04-10 devnull minus one on end of directory.
564 cfa37a7b 2004-04-10 devnull .TP
565 cfa37a7b 2004-04-10 devnull .I Write
566 cfa37a7b 2004-04-10 devnull The
567 cfa37a7b 2004-04-10 devnull .I write
568 cfa37a7b 2004-04-10 devnull function is similar but need not be provided.
569 cfa37a7b 2004-04-10 devnull If it is not, all writes will draw
570 cfa37a7b 2004-04-10 devnull ``write prohibited'' errors.
571 cfa37a7b 2004-04-10 devnull Otherwise,
572 cfa37a7b 2004-04-10 devnull .I write
573 cfa37a7b 2004-04-10 devnull should attempt to write the
574 cfa37a7b 2004-04-10 devnull .IB r -> ifcall . count
575 cfa37a7b 2004-04-10 devnull bytes of
576 cfa37a7b 2004-04-10 devnull .IB r -> ifcall . data
577 cfa37a7b 2004-04-10 devnull to offset
578 cfa37a7b 2004-04-10 devnull .IB r -> ifcall . offset
579 cfa37a7b 2004-04-10 devnull of the file, setting
580 cfa37a7b 2004-04-10 devnull .IB r -> ofcall . count
581 cfa37a7b 2004-04-10 devnull to the number of bytes actually written.
582 cfa37a7b 2004-04-10 devnull Most programs consider it an error to
583 cfa37a7b 2004-04-10 devnull write less than the requested amount.
584 cfa37a7b 2004-04-10 devnull .TP
585 cfa37a7b 2004-04-10 devnull .I Stat
586 cfa37a7b 2004-04-10 devnull .I Stat
587 cfa37a7b 2004-04-10 devnull should fill
588 cfa37a7b 2004-04-10 devnull .IB r -> d
589 cfa37a7b 2004-04-10 devnull with the stat information for
590 cfa37a7b 2004-04-10 devnull .IB r -> fid \fR.
591 cfa37a7b 2004-04-10 devnull If using file trees,
592 cfa37a7b 2004-04-10 devnull .IB r -> d
593 cfa37a7b 2004-04-10 devnull will have been initialized with the stat info from
594 cfa37a7b 2004-04-10 devnull the tree, and
595 cfa37a7b 2004-04-10 devnull .I stat
596 cfa37a7b 2004-04-10 devnull itself may be nil.
597 cfa37a7b 2004-04-10 devnull .TP
598 cfa37a7b 2004-04-10 devnull .I Wstat
599 cfa37a7b 2004-04-10 devnull The
600 cfa37a7b 2004-04-10 devnull .I wstat
601 cfa37a7b 2004-04-10 devnull consults
602 cfa37a7b 2004-04-10 devnull .IB r -> d
603 cfa37a7b 2004-04-10 devnull in changing the metadata for
604 cfa37a7b 2004-04-10 devnull .IB r -> fid
605 cfa37a7b 2004-04-10 devnull as described in
606 cfa37a7b 2004-04-10 devnull .IR stat (5).
607 cfa37a7b 2004-04-10 devnull When using file trees,
608 cfa37a7b 2004-04-10 devnull .I srv
609 cfa37a7b 2004-04-10 devnull will take care to check that the request satisfies
610 cfa37a7b 2004-04-10 devnull the permissions outlined in
611 cfa37a7b 2004-04-10 devnull .IR stat (5).
612 cfa37a7b 2004-04-10 devnull Otherwise
613 cfa37a7b 2004-04-10 devnull .I wstat
614 cfa37a7b 2004-04-10 devnull should take care to enforce permissions
615 cfa37a7b 2004-04-10 devnull where appropriate.
616 cfa37a7b 2004-04-10 devnull .TP
617 cfa37a7b 2004-04-10 devnull .I Flush
618 cfa37a7b 2004-04-10 devnull Single-threaded servers, which always call
619 cfa37a7b 2004-04-10 devnull .I respond
620 cfa37a7b 2004-04-10 devnull before returning from the service functions,
621 cfa37a7b 2004-04-10 devnull need not provide a
622 cfa37a7b 2004-04-10 devnull .I flush
623 cfa37a7b 2004-04-10 devnull implementation:
624 cfa37a7b 2004-04-10 devnull .I flush
625 cfa37a7b 2004-04-10 devnull is only necessary in multithreaded programs,
626 cfa37a7b 2004-04-10 devnull which arrange for
627 cfa37a7b 2004-04-10 devnull .I respond
628 cfa37a7b 2004-04-10 devnull to be called asynchronously.
629 cfa37a7b 2004-04-10 devnull .I Flush
630 cfa37a7b 2004-04-10 devnull should cause the request
631 cfa37a7b 2004-04-10 devnull .IB r -> oldreq
632 cfa37a7b 2004-04-10 devnull to be cancelled or hurried along.
633 cfa37a7b 2004-04-10 devnull If
634 cfa37a7b 2004-04-10 devnull .I oldreq
635 cfa37a7b 2004-04-10 devnull is cancelled, this should be signalled by calling
636 cfa37a7b 2004-04-10 devnull .I respond
637 cfa37a7b 2004-04-10 devnull on
638 cfa37a7b 2004-04-10 devnull .I oldreq
639 cfa37a7b 2004-04-10 devnull with error string
640 cfa37a7b 2004-04-10 devnull .RB ` interrupted '.
641 cfa37a7b 2004-04-10 devnull .I Flush
642 cfa37a7b 2004-04-10 devnull must respond to
643 cfa37a7b 2004-04-10 devnull .I r
644 cfa37a7b 2004-04-10 devnull with a nil error string.
645 cfa37a7b 2004-04-10 devnull .I Flush
646 cfa37a7b 2004-04-10 devnull may respond to
647 cfa37a7b 2004-04-10 devnull .I r
648 cfa37a7b 2004-04-10 devnull before forcing a response to
649 cfa37a7b 2004-04-10 devnull .IB r -> oldreq \fR.
650 cfa37a7b 2004-04-10 devnull In this case, the library will delay sending
651 cfa37a7b 2004-04-10 devnull the
652 cfa37a7b 2004-04-10 devnull .I Rflush
653 cfa37a7b 2004-04-10 devnull message until the response to
654 cfa37a7b 2004-04-10 devnull .IB r -> oldreq
655 cfa37a7b 2004-04-10 devnull has been sent.
656 cfa37a7b 2004-04-10 devnull .PD
657 cfa37a7b 2004-04-10 devnull .PP
658 cfa37a7b 2004-04-10 devnull .IR Destroyfid ,
659 cfa37a7b 2004-04-10 devnull .IR destroyreq ,
660 cfa37a7b 2004-04-10 devnull and
661 cfa37a7b 2004-04-10 devnull .I end
662 cfa37a7b 2004-04-10 devnull are auxiliary functions, not called in direct response to 9P requests.
663 cfa37a7b 2004-04-10 devnull .TP
664 cfa37a7b 2004-04-10 devnull .I Destroyfid
665 cfa37a7b 2004-04-10 devnull When a
666 cfa37a7b 2004-04-10 devnull .BR Fid 's
667 cfa37a7b 2004-04-10 devnull reference count drops to zero
668 cfa37a7b 2004-04-10 devnull .RI ( i.e.,
669 cfa37a7b 2004-04-10 devnull it has been clunked and there are no outstanding
670 cfa37a7b 2004-04-10 devnull requests referring to it),
671 cfa37a7b 2004-04-10 devnull .I destroyfid
672 cfa37a7b 2004-04-10 devnull is called to allow the program to dispose
673 cfa37a7b 2004-04-10 devnull of the
674 cfa37a7b 2004-04-10 devnull .IB fid -> aux
675 cfa37a7b 2004-04-10 devnull pointer.
676 cfa37a7b 2004-04-10 devnull .TP
677 cfa37a7b 2004-04-10 devnull .I Destroyreq
678 cfa37a7b 2004-04-10 devnull Similarly, when a
679 cfa37a7b 2004-04-10 devnull .BR Req 's
680 cfa37a7b 2004-04-10 devnull reference count drops to zero
681 cfa37a7b 2004-04-10 devnull .RI ( i.e. ,
682 cfa37a7b 2004-04-10 devnull it has been handled via
683 cfa37a7b 2004-04-10 devnull .I respond
684 cfa37a7b 2004-04-10 devnull and other outstanding pointers to it have been closed),
685 cfa37a7b 2004-04-10 devnull .I destroyreq
686 cfa37a7b 2004-04-10 devnull is called to allow the program to dispose of the
687 cfa37a7b 2004-04-10 devnull .IB r -> aux
688 cfa37a7b 2004-04-10 devnull pointer.
689 cfa37a7b 2004-04-10 devnull .TP
690 cfa37a7b 2004-04-10 devnull .I End
691 cfa37a7b 2004-04-10 devnull Once the 9P service loop has finished
692 cfa37a7b 2004-04-10 devnull (end of file been reached on the service pipe
693 cfa37a7b 2004-04-10 devnull or a bad message has been read),
694 cfa37a7b 2004-04-10 devnull .I end
695 cfa37a7b 2004-04-10 devnull is called (if provided) to allow any final cleanup.
696 cfa37a7b 2004-04-10 devnull For example, it was used by the Palm Pilot synchronization
697 cfa37a7b 2004-04-10 devnull file system (never finished) to gracefully terminate the serial conversation once
698 cfa37a7b 2004-04-10 devnull the file system had been unmounted.
699 cfa37a7b 2004-04-10 devnull After calling
700 cfa37a7b 2004-04-10 devnull .IR end ,
701 cfa37a7b 2004-04-10 devnull the service loop (which runs in a separate process
702 cfa37a7b 2004-04-10 devnull from its caller) terminates using
703 cfa37a7b 2004-04-10 devnull .I _exits
704 cfa37a7b 2004-04-10 devnull (see
705 bf8a59fa 2004-04-11 devnull .IR exits (3)).
706 cfa37a7b 2004-04-10 devnull .PD
707 cfa37a7b 2004-04-10 devnull .PP
708 cfa37a7b 2004-04-10 devnull If the
709 cfa37a7b 2004-04-10 devnull .B chatty9p
710 cfa37a7b 2004-04-10 devnull flag is at least one,
711 cfa37a7b 2004-04-10 devnull a transcript of the 9P session is printed
712 cfa37a7b 2004-04-10 devnull on standard error.
713 cfa37a7b 2004-04-10 devnull If the
714 cfa37a7b 2004-04-10 devnull .B chatty9p
715 cfa37a7b 2004-04-10 devnull flag is greater than one,
716 cfa37a7b 2004-04-10 devnull additional unspecified debugging output is generated.
717 cfa37a7b 2004-04-10 devnull By convention, servers written using this library
718 cfa37a7b 2004-04-10 devnull accept the
719 cfa37a7b 2004-04-10 devnull .B -D
720 cfa37a7b 2004-04-10 devnull option to increment
721 cfa37a7b 2004-04-10 devnull .BR chatty9p .
722 cfa37a7b 2004-04-10 devnull .SH EXAMPLES
723 cfa37a7b 2004-04-10 devnull .IR Archfs (4),
724 cfa37a7b 2004-04-10 devnull .IR cdfs (4),
725 cfa37a7b 2004-04-10 devnull .IR nntpfs (4),
726 cfa37a7b 2004-04-10 devnull .IR snap (4),
727 cfa37a7b 2004-04-10 devnull and
728 b5fdffee 2004-04-19 devnull .B /usr/local/plan9/src/lib9p/ramfs.c
729 cfa37a7b 2004-04-10 devnull are good examples of simple single-threaded file servers.
730 cfa37a7b 2004-04-10 devnull .IR Webfs (4)
731 cfa37a7b 2004-04-10 devnull and
732 cfa37a7b 2004-04-10 devnull .I sshnet
733 cfa37a7b 2004-04-10 devnull (see
734 cfa37a7b 2004-04-10 devnull .IR ssh (1))
735 cfa37a7b 2004-04-10 devnull are good examples of multithreaded file servers.
736 cfa37a7b 2004-04-10 devnull .PP
737 cfa37a7b 2004-04-10 devnull In general, the
738 cfa37a7b 2004-04-10 devnull .B File
739 cfa37a7b 2004-04-10 devnull interface is appropriate for maintaining arbitrary file trees (as in
740 cfa37a7b 2004-04-10 devnull .IR ramfs ).
741 cfa37a7b 2004-04-10 devnull The
742 cfa37a7b 2004-04-10 devnull .B File
743 cfa37a7b 2004-04-10 devnull interface is best avoided when the
744 cfa37a7b 2004-04-10 devnull tree structure is easily generated as necessary;
745 cfa37a7b 2004-04-10 devnull this is true when the tree is highly structured (as in
746 cfa37a7b 2004-04-10 devnull .I cdfs
747 cfa37a7b 2004-04-10 devnull and
748 cfa37a7b 2004-04-10 devnull .IR nntpfs )
749 cfa37a7b 2004-04-10 devnull or is maintained elsewhere.
750 cfa37a7b 2004-04-10 devnull .SH SOURCE
751 b5fdffee 2004-04-19 devnull .B /usr/local/plan9/src/lib9p
752 cfa37a7b 2004-04-10 devnull .SH SEE ALSO
753 bf8a59fa 2004-04-11 devnull .IR 9pfid (3),
754 bf8a59fa 2004-04-11 devnull .IR 9pfile (3),
755 cfa37a7b 2004-04-10 devnull .IR srv (3),
756 cfa37a7b 2004-04-10 devnull .IR intro (5)
757 cfa37a7b 2004-04-10 devnull .SH BUGS
758 cfa37a7b 2004-04-10 devnull The switch to 9P2000 was taken as an opportunity to tidy
759 cfa37a7b 2004-04-10 devnull much of the interface; we promise to avoid such gratuitous change
760 cfa37a7b 2004-04-10 devnull in the future.