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