Blame


1 d3df3087 2003-12-06 devnull #include <u.h>
2 d3df3087 2003-12-06 devnull #include <libc.h>
3 d3df3087 2003-12-06 devnull #include <fcall.h>
4 d3df3087 2003-12-06 devnull #include <thread.h>
5 32f69c36 2003-12-11 devnull #include <errno.h>
6 d3df3087 2003-12-06 devnull
7 d3df3087 2003-12-06 devnull enum
8 d3df3087 2003-12-06 devnull {
9 d3df3087 2003-12-06 devnull STACK = 32768,
10 d3df3087 2003-12-06 devnull NHASH = 31,
11 d3df3087 2003-12-06 devnull MAXMSG = 64, /* per connection */
12 d3df3087 2003-12-06 devnull };
13 d3df3087 2003-12-06 devnull
14 d3df3087 2003-12-06 devnull typedef struct Hash Hash;
15 d3df3087 2003-12-06 devnull typedef struct Fid Fid;
16 d3df3087 2003-12-06 devnull typedef struct Msg Msg;
17 d3df3087 2003-12-06 devnull typedef struct Conn Conn;
18 d3df3087 2003-12-06 devnull typedef struct Queue Queue;
19 d3df3087 2003-12-06 devnull
20 d3df3087 2003-12-06 devnull struct Hash
21 d3df3087 2003-12-06 devnull {
22 d3df3087 2003-12-06 devnull Hash *next;
23 d3df3087 2003-12-06 devnull uint n;
24 d3df3087 2003-12-06 devnull void *v;
25 d3df3087 2003-12-06 devnull };
26 d3df3087 2003-12-06 devnull
27 d3df3087 2003-12-06 devnull struct Fid
28 d3df3087 2003-12-06 devnull {
29 d3df3087 2003-12-06 devnull int fid;
30 d3df3087 2003-12-06 devnull int ref;
31 d3df3087 2003-12-06 devnull int cfid;
32 d3df3087 2003-12-06 devnull Fid *next;
33 d3df3087 2003-12-06 devnull };
34 d3df3087 2003-12-06 devnull
35 d3df3087 2003-12-06 devnull struct Msg
36 d3df3087 2003-12-06 devnull {
37 d3df3087 2003-12-06 devnull Conn *c;
38 d3df3087 2003-12-06 devnull int internal;
39 d3df3087 2003-12-06 devnull int ref;
40 d3df3087 2003-12-06 devnull int ctag;
41 d3df3087 2003-12-06 devnull int tag;
42 32f69c36 2003-12-11 devnull int isopenfd;
43 d3df3087 2003-12-06 devnull Fcall tx;
44 d3df3087 2003-12-06 devnull Fcall rx;
45 d3df3087 2003-12-06 devnull Fid *fid;
46 d3df3087 2003-12-06 devnull Fid *newfid;
47 d3df3087 2003-12-06 devnull Fid *afid;
48 d3df3087 2003-12-06 devnull Msg *oldm;
49 d3df3087 2003-12-06 devnull Msg *next;
50 d3df3087 2003-12-06 devnull uchar *tpkt;
51 d3df3087 2003-12-06 devnull uchar *rpkt;
52 d3df3087 2003-12-06 devnull };
53 d3df3087 2003-12-06 devnull
54 d3df3087 2003-12-06 devnull struct Conn
55 d3df3087 2003-12-06 devnull {
56 d3df3087 2003-12-06 devnull int fd;
57 32f69c36 2003-12-11 devnull int fdmode;
58 32f69c36 2003-12-11 devnull Fid *fdfid;
59 d3df3087 2003-12-06 devnull int nmsg;
60 d3df3087 2003-12-06 devnull int nfid;
61 d3df3087 2003-12-06 devnull Channel *inc;
62 d3df3087 2003-12-06 devnull Channel *internal;
63 d3df3087 2003-12-06 devnull int inputstalled;
64 d3df3087 2003-12-06 devnull char dir[40];
65 d3df3087 2003-12-06 devnull Hash *tag[NHASH];
66 d3df3087 2003-12-06 devnull Hash *fid[NHASH];
67 d3df3087 2003-12-06 devnull Queue *outq;
68 d3df3087 2003-12-06 devnull Queue *inq;
69 d3df3087 2003-12-06 devnull };
70 d3df3087 2003-12-06 devnull
71 d3df3087 2003-12-06 devnull char *addr;
72 d3df3087 2003-12-06 devnull int afd;
73 d3df3087 2003-12-06 devnull char adir[40];
74 d3df3087 2003-12-06 devnull int isunix;
75 d3df3087 2003-12-06 devnull Queue *outq;
76 d3df3087 2003-12-06 devnull Queue *inq;
77 05b7f431 2004-03-02 devnull int verbose = 0;
78 5a8e63b2 2004-02-29 devnull int msize = 8192;
79 d3df3087 2003-12-06 devnull
80 d3df3087 2003-12-06 devnull void *gethash(Hash**, uint);
81 d3df3087 2003-12-06 devnull int puthash(Hash**, uint, void*);
82 d3df3087 2003-12-06 devnull int delhash(Hash**, uint, void*);
83 ceb04770 2003-12-09 devnull Msg *mread9p(Ioproc*, int);
84 ceb04770 2003-12-09 devnull int mwrite9p(Ioproc*, int, uchar*);
85 ceb04770 2003-12-09 devnull uchar *read9ppkt(Ioproc*, int);
86 d3df3087 2003-12-06 devnull int write9ppkt(int, uchar*);
87 d3df3087 2003-12-06 devnull Msg *msgnew(void);
88 d3df3087 2003-12-06 devnull void msgput(Msg*);
89 d3df3087 2003-12-06 devnull Msg *msgget(int);
90 d3df3087 2003-12-06 devnull Fid *fidnew(int);
91 d3df3087 2003-12-06 devnull void fidput(Fid*);
92 d3df3087 2003-12-06 devnull void *emalloc(int);
93 d3df3087 2003-12-06 devnull void *erealloc(void*, int);
94 ceb04770 2003-12-09 devnull Queue *qalloc(void);
95 d3df3087 2003-12-06 devnull int sendq(Queue*, void*);
96 d3df3087 2003-12-06 devnull void *recvq(Queue*);
97 d3df3087 2003-12-06 devnull void connthread(void*);
98 ceb04770 2003-12-09 devnull void connoutthread(void*);
99 d3df3087 2003-12-06 devnull void listenthread(void*);
100 ceb04770 2003-12-09 devnull void outputthread(void*);
101 ceb04770 2003-12-09 devnull void inputthread(void*);
102 d3df3087 2003-12-06 devnull void rewritehdr(Fcall*, uchar*);
103 d3df3087 2003-12-06 devnull int tlisten(char*, char*);
104 d3df3087 2003-12-06 devnull int taccept(int, char*);
105 ceb04770 2003-12-09 devnull int iolisten(Ioproc*, char*, char*);
106 ceb04770 2003-12-09 devnull int ioaccept(Ioproc*, int, char*);
107 32f69c36 2003-12-11 devnull int iorecvfd(Ioproc*, int);
108 32f69c36 2003-12-11 devnull int iosendfd(Ioproc*, int, int);
109 32f69c36 2003-12-11 devnull void mainproc(void*);
110 32f69c36 2003-12-11 devnull int ignorepipe(void*, char*);
111 d3df3087 2003-12-06 devnull
112 d3df3087 2003-12-06 devnull void
113 d3df3087 2003-12-06 devnull usage(void)
114 d3df3087 2003-12-06 devnull {
115 ceb04770 2003-12-09 devnull fprint(2, "usage: 9pserve [-s service] [-u] address\n");
116 d3df3087 2003-12-06 devnull fprint(2, "\treads/writes 9P messages on stdin/stdout\n");
117 d3df3087 2003-12-06 devnull exits("usage");
118 d3df3087 2003-12-06 devnull }
119 d3df3087 2003-12-06 devnull
120 ceb04770 2003-12-09 devnull uchar vbuf[128];
121 32f69c36 2003-12-11 devnull extern int _threaddebuglevel;
122 d3df3087 2003-12-06 devnull void
123 d3df3087 2003-12-06 devnull threadmain(int argc, char **argv)
124 d3df3087 2003-12-06 devnull {
125 ceb04770 2003-12-09 devnull char *file;
126 ceb04770 2003-12-09 devnull
127 d3df3087 2003-12-06 devnull ARGBEGIN{
128 d3df3087 2003-12-06 devnull default:
129 d3df3087 2003-12-06 devnull usage();
130 ceb04770 2003-12-09 devnull case 'v':
131 ceb04770 2003-12-09 devnull verbose++;
132 ceb04770 2003-12-09 devnull break;
133 ceb04770 2003-12-09 devnull case 's':
134 ceb04770 2003-12-09 devnull close(0);
135 ceb04770 2003-12-09 devnull if(open(file=EARGF(usage()), ORDWR) != 0)
136 ceb04770 2003-12-09 devnull sysfatal("open %s: %r", file);
137 ceb04770 2003-12-09 devnull dup(0, 1);
138 ceb04770 2003-12-09 devnull break;
139 d3df3087 2003-12-06 devnull case 'u':
140 d3df3087 2003-12-06 devnull isunix = 1;
141 d3df3087 2003-12-06 devnull break;
142 d3df3087 2003-12-06 devnull }ARGEND
143 d3df3087 2003-12-06 devnull
144 5a8e63b2 2004-02-29 devnull if(verbose) fprint(2, "9pserve running\n");
145 d3df3087 2003-12-06 devnull if(argc != 1)
146 d3df3087 2003-12-06 devnull usage();
147 ceb04770 2003-12-09 devnull addr = argv[0];
148 d3df3087 2003-12-06 devnull
149 d3df3087 2003-12-06 devnull if((afd = announce(addr, adir)) < 0)
150 d3df3087 2003-12-06 devnull sysfatal("announce %s: %r", addr);
151 d3df3087 2003-12-06 devnull
152 5a8e63b2 2004-02-29 devnull if(verbose) fprint(2, "9pserve forking\n");
153 5a8e63b2 2004-02-29 devnull switch(fork()){
154 5a8e63b2 2004-02-29 devnull case -1:
155 5a8e63b2 2004-02-29 devnull sysfatal("fork: %r");
156 5a8e63b2 2004-02-29 devnull case 0:
157 5a8e63b2 2004-02-29 devnull if(verbose) fprint(2, "running mainproc\n");
158 5a8e63b2 2004-02-29 devnull mainproc(nil);
159 5a8e63b2 2004-02-29 devnull if(verbose) fprint(2, "mainproc finished\n");
160 5a8e63b2 2004-02-29 devnull _exits(0);
161 5a8e63b2 2004-02-29 devnull default:
162 5a8e63b2 2004-02-29 devnull if(verbose) fprint(2, "9pserve exiting\n");
163 5a8e63b2 2004-02-29 devnull _exits(0);
164 5a8e63b2 2004-02-29 devnull }
165 32f69c36 2003-12-11 devnull }
166 32f69c36 2003-12-11 devnull
167 32f69c36 2003-12-11 devnull void
168 32f69c36 2003-12-11 devnull mainproc(void *v)
169 32f69c36 2003-12-11 devnull {
170 c91bd328 2004-03-05 devnull int n, nn;
171 32f69c36 2003-12-11 devnull Fcall f;
172 32f69c36 2003-12-11 devnull USED(v);
173 32f69c36 2003-12-11 devnull
174 32f69c36 2003-12-11 devnull atnotify(ignorepipe, 1);
175 ceb04770 2003-12-09 devnull fmtinstall('D', dirfmt);
176 ceb04770 2003-12-09 devnull fmtinstall('M', dirmodefmt);
177 ceb04770 2003-12-09 devnull fmtinstall('F', fcallfmt);
178 ceb04770 2003-12-09 devnull fmtinstall('H', encodefmt);
179 ceb04770 2003-12-09 devnull
180 ceb04770 2003-12-09 devnull outq = qalloc();
181 ceb04770 2003-12-09 devnull inq = qalloc();
182 ceb04770 2003-12-09 devnull
183 ceb04770 2003-12-09 devnull f.type = Tversion;
184 ceb04770 2003-12-09 devnull f.version = "9P2000";
185 5a8e63b2 2004-02-29 devnull f.msize = msize;
186 ceb04770 2003-12-09 devnull f.tag = NOTAG;
187 ceb04770 2003-12-09 devnull n = convS2M(&f, vbuf, sizeof vbuf);
188 ceb04770 2003-12-09 devnull if(verbose > 1) fprint(2, "* <- %F\n", &f);
189 c91bd328 2004-03-05 devnull nn = write(1, vbuf, n);
190 c91bd328 2004-03-05 devnull if(n != nn)
191 c91bd328 2004-03-05 devnull sysfatal("error writing Tversion: %r\n");
192 c91bd328 2004-03-05 devnull n = threadread9pmsg(0, vbuf, sizeof vbuf);
193 ceb04770 2003-12-09 devnull if(convM2S(vbuf, n, &f) != n)
194 ceb04770 2003-12-09 devnull sysfatal("convM2S failure");
195 5a8e63b2 2004-02-29 devnull if(f.msize < msize)
196 5a8e63b2 2004-02-29 devnull msize = f.msize;
197 ceb04770 2003-12-09 devnull if(verbose > 1) fprint(2, "* -> %F\n", &f);
198 32f69c36 2003-12-11 devnull
199 32f69c36 2003-12-11 devnull threadcreate(inputthread, nil, STACK);
200 32f69c36 2003-12-11 devnull threadcreate(outputthread, nil, STACK);
201 ceb04770 2003-12-09 devnull threadcreate(listenthread, nil, STACK);
202 32f69c36 2003-12-11 devnull threadexits(0);
203 d3df3087 2003-12-06 devnull }
204 d3df3087 2003-12-06 devnull
205 32f69c36 2003-12-11 devnull int
206 32f69c36 2003-12-11 devnull ignorepipe(void *v, char *s)
207 32f69c36 2003-12-11 devnull {
208 32f69c36 2003-12-11 devnull USED(v);
209 32f69c36 2003-12-11 devnull if(strcmp(s, "sys: write on closed pipe") == 0)
210 32f69c36 2003-12-11 devnull return 1;
211 32f69c36 2003-12-11 devnull fprint(2, "msg: %s\n", s);
212 32f69c36 2003-12-11 devnull return 0;
213 32f69c36 2003-12-11 devnull }
214 32f69c36 2003-12-11 devnull
215 d3df3087 2003-12-06 devnull void
216 d3df3087 2003-12-06 devnull listenthread(void *arg)
217 d3df3087 2003-12-06 devnull {
218 d3df3087 2003-12-06 devnull Conn *c;
219 ceb04770 2003-12-09 devnull Ioproc *io;
220 d3df3087 2003-12-06 devnull
221 ceb04770 2003-12-09 devnull io = ioproc();
222 d3df3087 2003-12-06 devnull USED(arg);
223 d3df3087 2003-12-06 devnull for(;;){
224 ceb04770 2003-12-09 devnull c = emalloc(sizeof(Conn));
225 ceb04770 2003-12-09 devnull c->fd = iolisten(io, adir, c->dir);
226 d3df3087 2003-12-06 devnull if(c->fd < 0){
227 ceb04770 2003-12-09 devnull if(verbose) fprint(2, "listen: %r\n");
228 d3df3087 2003-12-06 devnull close(afd);
229 d3df3087 2003-12-06 devnull free(c);
230 d3df3087 2003-12-06 devnull return;
231 d3df3087 2003-12-06 devnull }
232 32f69c36 2003-12-11 devnull c->inc = chancreate(sizeof(void*), 0);
233 32f69c36 2003-12-11 devnull c->internal = chancreate(sizeof(void*), 0);
234 32f69c36 2003-12-11 devnull c->inq = qalloc();
235 32f69c36 2003-12-11 devnull c->outq = qalloc();
236 ceb04770 2003-12-09 devnull if(verbose) fprint(2, "incoming call on %s\n", c->dir);
237 d3df3087 2003-12-06 devnull threadcreate(connthread, c, STACK);
238 d3df3087 2003-12-06 devnull }
239 d3df3087 2003-12-06 devnull }
240 d3df3087 2003-12-06 devnull
241 d3df3087 2003-12-06 devnull void
242 32f69c36 2003-12-11 devnull send9pmsg(Msg *m)
243 d3df3087 2003-12-06 devnull {
244 d3df3087 2003-12-06 devnull int n, nn;
245 d3df3087 2003-12-06 devnull
246 d3df3087 2003-12-06 devnull n = sizeS2M(&m->rx);
247 d3df3087 2003-12-06 devnull m->rpkt = emalloc(n);
248 d3df3087 2003-12-06 devnull nn = convS2M(&m->rx, m->rpkt, n);
249 d3df3087 2003-12-06 devnull if(nn != n)
250 d3df3087 2003-12-06 devnull sysfatal("sizeS2M + convS2M disagree");
251 d3df3087 2003-12-06 devnull sendq(m->c->outq, m);
252 d3df3087 2003-12-06 devnull }
253 d3df3087 2003-12-06 devnull
254 d3df3087 2003-12-06 devnull void
255 ceb04770 2003-12-09 devnull sendomsg(Msg *m)
256 ceb04770 2003-12-09 devnull {
257 ceb04770 2003-12-09 devnull int n, nn;
258 ceb04770 2003-12-09 devnull
259 ceb04770 2003-12-09 devnull n = sizeS2M(&m->tx);
260 ceb04770 2003-12-09 devnull m->tpkt = emalloc(n);
261 ceb04770 2003-12-09 devnull nn = convS2M(&m->tx, m->tpkt, n);
262 ceb04770 2003-12-09 devnull if(nn != n)
263 ceb04770 2003-12-09 devnull sysfatal("sizeS2M + convS2M disagree");
264 ceb04770 2003-12-09 devnull sendq(outq, m);
265 ceb04770 2003-12-09 devnull }
266 ceb04770 2003-12-09 devnull
267 ceb04770 2003-12-09 devnull void
268 ceb04770 2003-12-09 devnull err(Msg *m, char *ename)
269 ceb04770 2003-12-09 devnull {
270 ceb04770 2003-12-09 devnull m->rx.type = Rerror;
271 ceb04770 2003-12-09 devnull m->rx.ename = ename;
272 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
273 32f69c36 2003-12-11 devnull send9pmsg(m);
274 ceb04770 2003-12-09 devnull }
275 ceb04770 2003-12-09 devnull
276 ceb04770 2003-12-09 devnull void
277 d3df3087 2003-12-06 devnull connthread(void *arg)
278 d3df3087 2003-12-06 devnull {
279 d3df3087 2003-12-06 devnull int i, fd;
280 d3df3087 2003-12-06 devnull Conn *c;
281 05b7f431 2004-03-02 devnull Hash *h, *hnext;
282 05b7f431 2004-03-02 devnull Msg *m, *om, *mm;
283 d3df3087 2003-12-06 devnull Fid *f;
284 ceb04770 2003-12-09 devnull Ioproc *io;
285 d3df3087 2003-12-06 devnull
286 d3df3087 2003-12-06 devnull c = arg;
287 ceb04770 2003-12-09 devnull io = ioproc();
288 ceb04770 2003-12-09 devnull fd = ioaccept(io, c->fd, c->dir);
289 d3df3087 2003-12-06 devnull if(fd < 0){
290 ceb04770 2003-12-09 devnull if(verbose) fprint(2, "accept %s: %r\n", c->dir);
291 d3df3087 2003-12-06 devnull goto out;
292 d3df3087 2003-12-06 devnull }
293 d3df3087 2003-12-06 devnull close(c->fd);
294 d3df3087 2003-12-06 devnull c->fd = fd;
295 ceb04770 2003-12-09 devnull threadcreate(connoutthread, c, STACK);
296 ceb04770 2003-12-09 devnull while((m = mread9p(io, c->fd)) != nil){
297 32f69c36 2003-12-11 devnull if(verbose > 1) fprint(2, "fd#%d -> %F\n", c->fd, &m->tx);
298 d3df3087 2003-12-06 devnull m->c = c;
299 ceb04770 2003-12-09 devnull m->ctag = m->tx.tag;
300 d3df3087 2003-12-06 devnull c->nmsg++;
301 d3df3087 2003-12-06 devnull if(puthash(c->tag, m->tx.tag, m) < 0){
302 d3df3087 2003-12-06 devnull err(m, "duplicate tag");
303 d3df3087 2003-12-06 devnull continue;
304 d3df3087 2003-12-06 devnull }
305 ceb04770 2003-12-09 devnull m->ref++;
306 d3df3087 2003-12-06 devnull switch(m->tx.type){
307 ceb04770 2003-12-09 devnull case Tversion:
308 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
309 ceb04770 2003-12-09 devnull m->rx.msize = m->tx.msize;
310 5a8e63b2 2004-02-29 devnull if(m->rx.msize > msize)
311 5a8e63b2 2004-02-29 devnull m->rx.msize = msize;
312 ceb04770 2003-12-09 devnull m->rx.version = "9P2000";
313 ceb04770 2003-12-09 devnull m->rx.type = Rversion;
314 32f69c36 2003-12-11 devnull send9pmsg(m);
315 ceb04770 2003-12-09 devnull continue;
316 d3df3087 2003-12-06 devnull case Tflush:
317 d3df3087 2003-12-06 devnull if((m->oldm = gethash(c->tag, m->tx.oldtag)) == nil){
318 ceb04770 2003-12-09 devnull m->rx.tag = m->tx.tag;
319 ceb04770 2003-12-09 devnull m->rx.type = Rflush;
320 32f69c36 2003-12-11 devnull send9pmsg(m);
321 d3df3087 2003-12-06 devnull continue;
322 d3df3087 2003-12-06 devnull }
323 ceb04770 2003-12-09 devnull m->oldm->ref++;
324 d3df3087 2003-12-06 devnull break;
325 d3df3087 2003-12-06 devnull case Tattach:
326 ceb04770 2003-12-09 devnull m->afid = nil;
327 ceb04770 2003-12-09 devnull if(m->tx.afid != NOFID
328 ceb04770 2003-12-09 devnull && (m->afid = gethash(c->fid, m->tx.afid)) == nil){
329 ceb04770 2003-12-09 devnull err(m, "unknown fid");
330 ceb04770 2003-12-09 devnull continue;
331 ceb04770 2003-12-09 devnull }
332 d3df3087 2003-12-06 devnull m->fid = fidnew(m->tx.fid);
333 d3df3087 2003-12-06 devnull if(puthash(c->fid, m->tx.fid, m->fid) < 0){
334 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
335 d3df3087 2003-12-06 devnull continue;
336 d3df3087 2003-12-06 devnull }
337 d3df3087 2003-12-06 devnull m->fid->ref++;
338 d3df3087 2003-12-06 devnull break;
339 d3df3087 2003-12-06 devnull case Twalk:
340 d3df3087 2003-12-06 devnull if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
341 d3df3087 2003-12-06 devnull err(m, "unknown fid");
342 d3df3087 2003-12-06 devnull continue;
343 d3df3087 2003-12-06 devnull }
344 ceb04770 2003-12-09 devnull m->fid->ref++;
345 d3df3087 2003-12-06 devnull if(m->tx.newfid == m->tx.fid){
346 d3df3087 2003-12-06 devnull m->fid->ref++;
347 d3df3087 2003-12-06 devnull m->newfid = m->fid;
348 d3df3087 2003-12-06 devnull }else{
349 d3df3087 2003-12-06 devnull m->newfid = fidnew(m->tx.newfid);
350 d3df3087 2003-12-06 devnull if(puthash(c->fid, m->tx.newfid, m->newfid) < 0){
351 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
352 d3df3087 2003-12-06 devnull continue;
353 d3df3087 2003-12-06 devnull }
354 d3df3087 2003-12-06 devnull m->newfid->ref++;
355 d3df3087 2003-12-06 devnull }
356 d3df3087 2003-12-06 devnull break;
357 d3df3087 2003-12-06 devnull case Tauth:
358 ceb04770 2003-12-09 devnull m->afid = fidnew(m->tx.afid);
359 ceb04770 2003-12-09 devnull if(puthash(c->fid, m->tx.afid, m->afid) < 0){
360 d3df3087 2003-12-06 devnull err(m, "duplicate fid");
361 d3df3087 2003-12-06 devnull continue;
362 d3df3087 2003-12-06 devnull }
363 ceb04770 2003-12-09 devnull m->afid->ref++;
364 d3df3087 2003-12-06 devnull break;
365 32f69c36 2003-12-11 devnull case Topenfd:
366 49588d5d 2003-12-17 devnull if(m->tx.mode&~(OTRUNC|3)){
367 49588d5d 2003-12-17 devnull err(m, "bad openfd mode");
368 32f69c36 2003-12-11 devnull continue;
369 32f69c36 2003-12-11 devnull }
370 32f69c36 2003-12-11 devnull m->isopenfd = 1;
371 32f69c36 2003-12-11 devnull m->tx.type = Topen;
372 32f69c36 2003-12-11 devnull m->tpkt[4] = Topen;
373 32f69c36 2003-12-11 devnull /* fall through */
374 ceb04770 2003-12-09 devnull case Tcreate:
375 d3df3087 2003-12-06 devnull case Topen:
376 d3df3087 2003-12-06 devnull case Tclunk:
377 d3df3087 2003-12-06 devnull case Tread:
378 d3df3087 2003-12-06 devnull case Twrite:
379 ceb04770 2003-12-09 devnull case Tremove:
380 d3df3087 2003-12-06 devnull case Tstat:
381 d3df3087 2003-12-06 devnull case Twstat:
382 d3df3087 2003-12-06 devnull if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
383 d3df3087 2003-12-06 devnull err(m, "unknown fid");
384 d3df3087 2003-12-06 devnull continue;
385 d3df3087 2003-12-06 devnull }
386 d3df3087 2003-12-06 devnull m->fid->ref++;
387 d3df3087 2003-12-06 devnull break;
388 d3df3087 2003-12-06 devnull }
389 d3df3087 2003-12-06 devnull
390 d3df3087 2003-12-06 devnull /* have everything - translate and send */
391 d3df3087 2003-12-06 devnull m->c = c;
392 d3df3087 2003-12-06 devnull m->ctag = m->tx.tag;
393 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
394 d3df3087 2003-12-06 devnull if(m->fid)
395 d3df3087 2003-12-06 devnull m->tx.fid = m->fid->fid;
396 d3df3087 2003-12-06 devnull if(m->newfid)
397 d3df3087 2003-12-06 devnull m->tx.newfid = m->newfid->fid;
398 d3df3087 2003-12-06 devnull if(m->afid)
399 d3df3087 2003-12-06 devnull m->tx.afid = m->afid->fid;
400 d3df3087 2003-12-06 devnull if(m->oldm)
401 d3df3087 2003-12-06 devnull m->tx.oldtag = m->oldm->tag;
402 ceb04770 2003-12-09 devnull /* reference passes to outq */
403 d3df3087 2003-12-06 devnull sendq(outq, m);
404 d3df3087 2003-12-06 devnull while(c->nmsg >= MAXMSG){
405 d3df3087 2003-12-06 devnull c->inputstalled = 1;
406 d3df3087 2003-12-06 devnull recvp(c->inc);
407 d3df3087 2003-12-06 devnull }
408 d3df3087 2003-12-06 devnull }
409 d3df3087 2003-12-06 devnull
410 05b7f431 2004-03-02 devnull if(verbose) fprint(2, "fd#%d eof; flushing conn\n", c->fd);
411 05b7f431 2004-03-02 devnull
412 05b7f431 2004-03-02 devnull /* flush the output queue */
413 05b7f431 2004-03-02 devnull sendq(c->outq, nil);
414 05b7f431 2004-03-02 devnull while(c->outq != nil)
415 05b7f431 2004-03-02 devnull yield();
416 ceb04770 2003-12-09 devnull
417 d3df3087 2003-12-06 devnull /* flush all outstanding messages */
418 d3df3087 2003-12-06 devnull for(i=0; i<NHASH; i++){
419 05b7f431 2004-03-02 devnull for(h=c->tag[i]; h; h=hnext){
420 d3df3087 2003-12-06 devnull om = h->v;
421 d3df3087 2003-12-06 devnull m = msgnew();
422 d3df3087 2003-12-06 devnull m->internal = 1;
423 d3df3087 2003-12-06 devnull m->c = c;
424 32f69c36 2003-12-11 devnull c->nmsg++;
425 d3df3087 2003-12-06 devnull m->tx.type = Tflush;
426 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
427 d3df3087 2003-12-06 devnull m->tx.oldtag = om->tag;
428 d3df3087 2003-12-06 devnull m->oldm = om;
429 05b7f431 2004-03-02 devnull om->ref++; /* for m->oldm */
430 ceb04770 2003-12-09 devnull m->ref++; /* for outq */
431 ceb04770 2003-12-09 devnull sendomsg(m);
432 05b7f431 2004-03-02 devnull mm = recvp(c->internal);
433 05b7f431 2004-03-02 devnull assert(mm == m);
434 32f69c36 2003-12-11 devnull msgput(m); /* got from recvp */
435 32f69c36 2003-12-11 devnull msgput(m); /* got from msgnew */
436 32f69c36 2003-12-11 devnull msgput(om); /* got from hash table */
437 05b7f431 2004-03-02 devnull hnext = h->next;
438 05b7f431 2004-03-02 devnull free(h);
439 d3df3087 2003-12-06 devnull }
440 d3df3087 2003-12-06 devnull }
441 d3df3087 2003-12-06 devnull
442 d3df3087 2003-12-06 devnull /* clunk all outstanding fids */
443 d3df3087 2003-12-06 devnull for(i=0; i<NHASH; i++){
444 05b7f431 2004-03-02 devnull for(h=c->fid[i]; h; h=hnext){
445 d3df3087 2003-12-06 devnull f = h->v;
446 d3df3087 2003-12-06 devnull m = msgnew();
447 d3df3087 2003-12-06 devnull m->internal = 1;
448 d3df3087 2003-12-06 devnull m->c = c;
449 32f69c36 2003-12-11 devnull c->nmsg++;
450 d3df3087 2003-12-06 devnull m->tx.type = Tclunk;
451 d3df3087 2003-12-06 devnull m->tx.tag = m->tag;
452 d3df3087 2003-12-06 devnull m->tx.fid = f->fid;
453 d3df3087 2003-12-06 devnull m->fid = f;
454 d3df3087 2003-12-06 devnull f->ref++;
455 ceb04770 2003-12-09 devnull m->ref++;
456 ceb04770 2003-12-09 devnull sendomsg(m);
457 05b7f431 2004-03-02 devnull mm = recvp(c->internal);
458 05b7f431 2004-03-02 devnull assert(mm == m);
459 32f69c36 2003-12-11 devnull msgput(m); /* got from recvp */
460 32f69c36 2003-12-11 devnull msgput(m); /* got from msgnew */
461 32f69c36 2003-12-11 devnull fidput(f); /* got from hash table */
462 05b7f431 2004-03-02 devnull hnext = h->next;
463 05b7f431 2004-03-02 devnull free(h);
464 d3df3087 2003-12-06 devnull }
465 d3df3087 2003-12-06 devnull }
466 d3df3087 2003-12-06 devnull
467 d3df3087 2003-12-06 devnull out:
468 d3df3087 2003-12-06 devnull assert(c->nmsg == 0);
469 d3df3087 2003-12-06 devnull assert(c->nfid == 0);
470 d3df3087 2003-12-06 devnull close(c->fd);
471 32f69c36 2003-12-11 devnull chanfree(c->internal);
472 32f69c36 2003-12-11 devnull c->internal = 0;
473 32f69c36 2003-12-11 devnull chanfree(c->inc);
474 32f69c36 2003-12-11 devnull c->inc = 0;
475 32f69c36 2003-12-11 devnull free(c->inq);
476 32f69c36 2003-12-11 devnull c->inq = 0;
477 d3df3087 2003-12-06 devnull free(c);
478 d3df3087 2003-12-06 devnull }
479 32f69c36 2003-12-11 devnull
480 32f69c36 2003-12-11 devnull static void
481 32f69c36 2003-12-11 devnull openfdthread(void *v)
482 32f69c36 2003-12-11 devnull {
483 32f69c36 2003-12-11 devnull Conn *c;
484 32f69c36 2003-12-11 devnull Fid *fid;
485 32f69c36 2003-12-11 devnull Msg *m;
486 32f69c36 2003-12-11 devnull int n;
487 32f69c36 2003-12-11 devnull vlong tot;
488 32f69c36 2003-12-11 devnull Ioproc *io;
489 32f69c36 2003-12-11 devnull char buf[1024];
490 32f69c36 2003-12-11 devnull
491 32f69c36 2003-12-11 devnull c = v;
492 32f69c36 2003-12-11 devnull fid = c->fdfid;
493 32f69c36 2003-12-11 devnull io = ioproc();
494 32f69c36 2003-12-11 devnull
495 32f69c36 2003-12-11 devnull tot = 0;
496 05b7f431 2004-03-02 devnull m = nil;
497 32f69c36 2003-12-11 devnull if(c->fdmode == OREAD){
498 32f69c36 2003-12-11 devnull for(;;){
499 32f69c36 2003-12-11 devnull if(verbose) fprint(2, "tread...");
500 32f69c36 2003-12-11 devnull m = msgnew();
501 32f69c36 2003-12-11 devnull m->internal = 1;
502 32f69c36 2003-12-11 devnull m->c = c;
503 32f69c36 2003-12-11 devnull m->tx.type = Tread;
504 5a8e63b2 2004-02-29 devnull m->tx.count = msize - IOHDRSZ;
505 32f69c36 2003-12-11 devnull m->tx.fid = fid->fid;
506 32f69c36 2003-12-11 devnull m->tx.tag = m->tag;
507 32f69c36 2003-12-11 devnull m->tx.offset = tot;
508 32f69c36 2003-12-11 devnull m->fid = fid;
509 32f69c36 2003-12-11 devnull fid->ref++;
510 32f69c36 2003-12-11 devnull m->ref++;
511 32f69c36 2003-12-11 devnull sendomsg(m);
512 32f69c36 2003-12-11 devnull recvp(c->internal);
513 49588d5d 2003-12-17 devnull if(m->rx.type == Rerror){
514 49588d5d 2003-12-17 devnull // fprint(2, "read error: %s\n", m->rx.ename);
515 32f69c36 2003-12-11 devnull break;
516 49588d5d 2003-12-17 devnull }
517 32f69c36 2003-12-11 devnull if(m->rx.count == 0)
518 32f69c36 2003-12-11 devnull break;
519 32f69c36 2003-12-11 devnull tot += m->rx.count;
520 49588d5d 2003-12-17 devnull if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count){
521 05b7f431 2004-03-02 devnull // fprint(2, "pipe write error: %r\n");
522 32f69c36 2003-12-11 devnull break;
523 49588d5d 2003-12-17 devnull }
524 32f69c36 2003-12-11 devnull msgput(m);
525 32f69c36 2003-12-11 devnull msgput(m);
526 05b7f431 2004-03-02 devnull m = nil;
527 32f69c36 2003-12-11 devnull }
528 32f69c36 2003-12-11 devnull }else{
529 32f69c36 2003-12-11 devnull for(;;){
530 32f69c36 2003-12-11 devnull if(verbose) fprint(2, "twrite...");
531 5a8e63b2 2004-02-29 devnull n = sizeof buf;
532 5a8e63b2 2004-02-29 devnull if(n > msize)
533 5a8e63b2 2004-02-29 devnull n = msize;
534 5a8e63b2 2004-02-29 devnull if((n=ioread(io, c->fd, buf, n)) <= 0){
535 49588d5d 2003-12-17 devnull if(n < 0)
536 49588d5d 2003-12-17 devnull fprint(2, "pipe read error: %r\n");
537 32f69c36 2003-12-11 devnull break;
538 32f69c36 2003-12-11 devnull }
539 32f69c36 2003-12-11 devnull m = msgnew();
540 32f69c36 2003-12-11 devnull m->internal = 1;
541 32f69c36 2003-12-11 devnull m->c = c;
542 32f69c36 2003-12-11 devnull m->tx.type = Twrite;
543 32f69c36 2003-12-11 devnull m->tx.fid = fid->fid;
544 32f69c36 2003-12-11 devnull m->tx.data = buf;
545 32f69c36 2003-12-11 devnull m->tx.count = n;
546 32f69c36 2003-12-11 devnull m->tx.tag = m->tag;
547 32f69c36 2003-12-11 devnull m->tx.offset = tot;
548 32f69c36 2003-12-11 devnull m->fid = fid;
549 32f69c36 2003-12-11 devnull fid->ref++;
550 32f69c36 2003-12-11 devnull m->ref++;
551 32f69c36 2003-12-11 devnull sendomsg(m);
552 32f69c36 2003-12-11 devnull recvp(c->internal);
553 49588d5d 2003-12-17 devnull if(m->rx.type == Rerror){
554 49588d5d 2003-12-17 devnull // fprint(2, "write error: %s\n", m->rx.ename);
555 49588d5d 2003-12-17 devnull }
556 05b7f431 2004-03-02 devnull tot += n;
557 32f69c36 2003-12-11 devnull msgput(m);
558 32f69c36 2003-12-11 devnull msgput(m);
559 05b7f431 2004-03-02 devnull m = nil;
560 32f69c36 2003-12-11 devnull }
561 32f69c36 2003-12-11 devnull }
562 32f69c36 2003-12-11 devnull if(verbose) fprint(2, "eof on %d fid %d\n", c->fd, fid->fid);
563 32f69c36 2003-12-11 devnull close(c->fd);
564 32f69c36 2003-12-11 devnull closeioproc(io);
565 32f69c36 2003-12-11 devnull if(m){
566 32f69c36 2003-12-11 devnull msgput(m);
567 32f69c36 2003-12-11 devnull msgput(m);
568 32f69c36 2003-12-11 devnull }
569 49588d5d 2003-12-17 devnull if(fid->ref == 1){
570 49588d5d 2003-12-17 devnull m = msgnew();
571 49588d5d 2003-12-17 devnull m->internal = 1;
572 49588d5d 2003-12-17 devnull m->c = c;
573 49588d5d 2003-12-17 devnull m->tx.type = Tclunk;
574 05b7f431 2004-03-02 devnull m->tx.tag = m->tag;
575 49588d5d 2003-12-17 devnull m->tx.fid = fid->fid;
576 49588d5d 2003-12-17 devnull m->fid = fid;
577 49588d5d 2003-12-17 devnull fid->ref++;
578 49588d5d 2003-12-17 devnull m->ref++;
579 49588d5d 2003-12-17 devnull sendomsg(m);
580 49588d5d 2003-12-17 devnull recvp(c->internal);
581 49588d5d 2003-12-17 devnull msgput(m);
582 49588d5d 2003-12-17 devnull msgput(m);
583 49588d5d 2003-12-17 devnull }
584 32f69c36 2003-12-11 devnull fidput(fid);
585 32f69c36 2003-12-11 devnull c->fdfid = nil;
586 32f69c36 2003-12-11 devnull chanfree(c->internal);
587 32f69c36 2003-12-11 devnull c->internal = 0;
588 32f69c36 2003-12-11 devnull free(c);
589 32f69c36 2003-12-11 devnull }
590 d3df3087 2003-12-06 devnull
591 32f69c36 2003-12-11 devnull int
592 32f69c36 2003-12-11 devnull xopenfd(Msg *m)
593 32f69c36 2003-12-11 devnull {
594 32f69c36 2003-12-11 devnull char errs[ERRMAX];
595 32f69c36 2003-12-11 devnull int n, p[2];
596 32f69c36 2003-12-11 devnull Conn *nc;
597 32f69c36 2003-12-11 devnull
598 32f69c36 2003-12-11 devnull if(pipe(p) < 0){
599 32f69c36 2003-12-11 devnull rerrstr(errs, sizeof errs);
600 32f69c36 2003-12-11 devnull err(m, errs);
601 32f69c36 2003-12-11 devnull }
602 32f69c36 2003-12-11 devnull if(verbose) fprint(2, "xopen pipe %d %d...", p[0], p[1]);
603 32f69c36 2003-12-11 devnull
604 32f69c36 2003-12-11 devnull /* now we're committed. */
605 32f69c36 2003-12-11 devnull
606 32f69c36 2003-12-11 devnull /* a new connection for this fid */
607 32f69c36 2003-12-11 devnull nc = emalloc(sizeof(Conn));
608 32f69c36 2003-12-11 devnull nc->internal = chancreate(sizeof(void*), 0);
609 32f69c36 2003-12-11 devnull
610 32f69c36 2003-12-11 devnull /* a ref for us */
611 32f69c36 2003-12-11 devnull nc->fdfid = m->fid;
612 32f69c36 2003-12-11 devnull m->fid->ref++;
613 32f69c36 2003-12-11 devnull nc->fdmode = m->tx.mode;
614 32f69c36 2003-12-11 devnull nc->fd = p[0];
615 32f69c36 2003-12-11 devnull
616 32f69c36 2003-12-11 devnull /* a thread to tend the pipe */
617 32f69c36 2003-12-11 devnull threadcreate(openfdthread, nc, STACK);
618 32f69c36 2003-12-11 devnull
619 49588d5d 2003-12-17 devnull /* if mode is ORDWR, that openfdthread will write; start a reader */
620 49588d5d 2003-12-17 devnull if((m->tx.mode&3) == ORDWR){
621 49588d5d 2003-12-17 devnull nc = emalloc(sizeof(Conn));
622 49588d5d 2003-12-17 devnull nc->internal = chancreate(sizeof(void*), 0);
623 49588d5d 2003-12-17 devnull nc->fdfid = m->fid;
624 49588d5d 2003-12-17 devnull m->fid->ref++;
625 49588d5d 2003-12-17 devnull nc->fdmode = OREAD;
626 49588d5d 2003-12-17 devnull nc->fd = dup(p[0], -1);
627 49588d5d 2003-12-17 devnull threadcreate(openfdthread, nc, STACK);
628 49588d5d 2003-12-17 devnull }
629 49588d5d 2003-12-17 devnull
630 49588d5d 2003-12-17 devnull /* steal fid from other connection */
631 49588d5d 2003-12-17 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
632 49588d5d 2003-12-17 devnull fidput(m->fid);
633 49588d5d 2003-12-17 devnull
634 32f69c36 2003-12-11 devnull /* rewrite as Ropenfd */
635 32f69c36 2003-12-11 devnull m->rx.type = Ropenfd;
636 32f69c36 2003-12-11 devnull n = GBIT32(m->rpkt);
637 32f69c36 2003-12-11 devnull m->rpkt = erealloc(m->rpkt, n+4);
638 32f69c36 2003-12-11 devnull PBIT32(m->rpkt+n, p[1]);
639 32f69c36 2003-12-11 devnull n += 4;
640 32f69c36 2003-12-11 devnull PBIT32(m->rpkt, n);
641 32f69c36 2003-12-11 devnull m->rpkt[4] = Ropenfd;
642 32f69c36 2003-12-11 devnull m->rx.unixfd = p[1];
643 32f69c36 2003-12-11 devnull return 0;
644 32f69c36 2003-12-11 devnull }
645 32f69c36 2003-12-11 devnull
646 d3df3087 2003-12-06 devnull void
647 d3df3087 2003-12-06 devnull connoutthread(void *arg)
648 d3df3087 2003-12-06 devnull {
649 d3df3087 2003-12-06 devnull int err;
650 d3df3087 2003-12-06 devnull Conn *c;
651 05b7f431 2004-03-02 devnull Queue *outq;
652 d3df3087 2003-12-06 devnull Msg *m, *om;
653 ceb04770 2003-12-09 devnull Ioproc *io;
654 d3df3087 2003-12-06 devnull
655 d3df3087 2003-12-06 devnull c = arg;
656 05b7f431 2004-03-02 devnull outq = c->outq;
657 ceb04770 2003-12-09 devnull io = ioproc();
658 05b7f431 2004-03-02 devnull while((m = recvq(outq)) != nil){
659 d3df3087 2003-12-06 devnull err = m->tx.type+1 != m->rx.type;
660 32f69c36 2003-12-11 devnull if(!err && m->isopenfd)
661 32f69c36 2003-12-11 devnull if(xopenfd(m) < 0)
662 32f69c36 2003-12-11 devnull continue;
663 d3df3087 2003-12-06 devnull switch(m->tx.type){
664 d3df3087 2003-12-06 devnull case Tflush:
665 d3df3087 2003-12-06 devnull om = m->oldm;
666 ceb04770 2003-12-09 devnull if(om)
667 ceb04770 2003-12-09 devnull if(delhash(om->c->tag, om->ctag, om) == 0)
668 ceb04770 2003-12-09 devnull msgput(om);
669 d3df3087 2003-12-06 devnull break;
670 d3df3087 2003-12-06 devnull case Tclunk:
671 ceb04770 2003-12-09 devnull case Tremove:
672 ceb04770 2003-12-09 devnull if(m->fid)
673 ceb04770 2003-12-09 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
674 ceb04770 2003-12-09 devnull fidput(m->fid);
675 d3df3087 2003-12-06 devnull break;
676 d3df3087 2003-12-06 devnull case Tauth:
677 ceb04770 2003-12-09 devnull if(err && m->afid){
678 ceb04770 2003-12-09 devnull fprint(2, "auth error\n");
679 ceb04770 2003-12-09 devnull if(delhash(m->c->fid, m->afid->cfid, m->afid) == 0)
680 d3df3087 2003-12-06 devnull fidput(m->fid);
681 ceb04770 2003-12-09 devnull }
682 ceb04770 2003-12-09 devnull break;
683 d3df3087 2003-12-06 devnull case Tattach:
684 ceb04770 2003-12-09 devnull if(err && m->fid)
685 d3df3087 2003-12-06 devnull if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
686 d3df3087 2003-12-06 devnull fidput(m->fid);
687 d3df3087 2003-12-06 devnull break;
688 d3df3087 2003-12-06 devnull case Twalk:
689 ceb04770 2003-12-09 devnull if(err && m->tx.fid != m->tx.newfid && m->newfid)
690 d3df3087 2003-12-06 devnull if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0)
691 d3df3087 2003-12-06 devnull fidput(m->newfid);
692 d3df3087 2003-12-06 devnull break;
693 d3df3087 2003-12-06 devnull }
694 d3df3087 2003-12-06 devnull if(delhash(m->c->tag, m->ctag, m) == 0)
695 d3df3087 2003-12-06 devnull msgput(m);
696 32f69c36 2003-12-11 devnull if(verbose > 1) fprint(2, "fd#%d <- %F\n", c->fd, &m->rx);
697 ceb04770 2003-12-09 devnull rewritehdr(&m->rx, m->rpkt);
698 ceb04770 2003-12-09 devnull if(mwrite9p(io, c->fd, m->rpkt) < 0)
699 ceb04770 2003-12-09 devnull if(verbose) fprint(2, "write error: %r\n");
700 d3df3087 2003-12-06 devnull msgput(m);
701 d3df3087 2003-12-06 devnull if(c->inputstalled && c->nmsg < MAXMSG)
702 d3df3087 2003-12-06 devnull nbsendp(c->inc, 0);
703 d3df3087 2003-12-06 devnull }
704 ceb04770 2003-12-09 devnull closeioproc(io);
705 05b7f431 2004-03-02 devnull free(outq);
706 05b7f431 2004-03-02 devnull c->outq = nil;
707 d3df3087 2003-12-06 devnull }
708 d3df3087 2003-12-06 devnull
709 d3df3087 2003-12-06 devnull void
710 d3df3087 2003-12-06 devnull outputthread(void *arg)
711 d3df3087 2003-12-06 devnull {
712 d3df3087 2003-12-06 devnull Msg *m;
713 ceb04770 2003-12-09 devnull Ioproc *io;
714 d3df3087 2003-12-06 devnull
715 d3df3087 2003-12-06 devnull USED(arg);
716 ceb04770 2003-12-09 devnull io = ioproc();
717 d3df3087 2003-12-06 devnull while((m = recvq(outq)) != nil){
718 ceb04770 2003-12-09 devnull if(verbose > 1) fprint(2, "* <- %F\n", &m->tx);
719 ceb04770 2003-12-09 devnull rewritehdr(&m->tx, m->tpkt);
720 ceb04770 2003-12-09 devnull if(mwrite9p(io, 1, m->tpkt) < 0)
721 d3df3087 2003-12-06 devnull sysfatal("output error: %r");
722 d3df3087 2003-12-06 devnull msgput(m);
723 d3df3087 2003-12-06 devnull }
724 ceb04770 2003-12-09 devnull closeioproc(io);
725 32f69c36 2003-12-11 devnull fprint(2, "output eof\n");
726 32f69c36 2003-12-11 devnull threadexitsall(0);
727 d3df3087 2003-12-06 devnull }
728 d3df3087 2003-12-06 devnull
729 d3df3087 2003-12-06 devnull void
730 d3df3087 2003-12-06 devnull inputthread(void *arg)
731 d3df3087 2003-12-06 devnull {
732 d3df3087 2003-12-06 devnull uchar *pkt;
733 d3df3087 2003-12-06 devnull int n, nn, tag;
734 d3df3087 2003-12-06 devnull Msg *m;
735 ceb04770 2003-12-09 devnull Ioproc *io;
736 d3df3087 2003-12-06 devnull
737 32f69c36 2003-12-11 devnull if(verbose) fprint(2, "input thread\n");
738 ceb04770 2003-12-09 devnull io = ioproc();
739 ceb04770 2003-12-09 devnull USED(arg);
740 ceb04770 2003-12-09 devnull while((pkt = read9ppkt(io, 0)) != nil){
741 d3df3087 2003-12-06 devnull n = GBIT32(pkt);
742 d3df3087 2003-12-06 devnull if(n < 7){
743 ceb04770 2003-12-09 devnull fprint(2, "short 9P packet from server\n");
744 d3df3087 2003-12-06 devnull free(pkt);
745 d3df3087 2003-12-06 devnull continue;
746 d3df3087 2003-12-06 devnull }
747 ceb04770 2003-12-09 devnull if(verbose > 2) fprint(2, "read %.*H\n", n, pkt);
748 d3df3087 2003-12-06 devnull tag = GBIT16(pkt+5);
749 d3df3087 2003-12-06 devnull if((m = msgget(tag)) == nil){
750 d3df3087 2003-12-06 devnull fprint(2, "unexpected 9P response tag %d\n", tag);
751 d3df3087 2003-12-06 devnull free(pkt);
752 d3df3087 2003-12-06 devnull continue;
753 d3df3087 2003-12-06 devnull }
754 d3df3087 2003-12-06 devnull if((nn = convM2S(pkt, n, &m->rx)) != n){
755 d3df3087 2003-12-06 devnull fprint(2, "bad packet - convM2S %d but %d\n", nn, n);
756 d3df3087 2003-12-06 devnull free(pkt);
757 d3df3087 2003-12-06 devnull msgput(m);
758 d3df3087 2003-12-06 devnull continue;
759 d3df3087 2003-12-06 devnull }
760 05b7f431 2004-03-02 devnull if(verbose > 1) fprint(2, "* -> %F%s\n", &m->rx,
761 05b7f431 2004-03-02 devnull m->internal ? " (internal)" : "");
762 d3df3087 2003-12-06 devnull m->rpkt = pkt;
763 d3df3087 2003-12-06 devnull m->rx.tag = m->ctag;
764 ceb04770 2003-12-09 devnull if(m->internal)
765 05b7f431 2004-03-02 devnull sendp(m->c->internal, m);
766 05b7f431 2004-03-02 devnull else if(m->c->outq)
767 ceb04770 2003-12-09 devnull sendq(m->c->outq, m);
768 05b7f431 2004-03-02 devnull else
769 05b7f431 2004-03-02 devnull msgput(m);
770 d3df3087 2003-12-06 devnull }
771 ceb04770 2003-12-09 devnull closeioproc(io);
772 f063dad9 2004-02-29 devnull //fprint(2, "input eof\n");
773 32f69c36 2003-12-11 devnull threadexitsall(0);
774 d3df3087 2003-12-06 devnull }
775 d3df3087 2003-12-06 devnull
776 d3df3087 2003-12-06 devnull void*
777 d3df3087 2003-12-06 devnull gethash(Hash **ht, uint n)
778 d3df3087 2003-12-06 devnull {
779 d3df3087 2003-12-06 devnull Hash *h;
780 d3df3087 2003-12-06 devnull
781 d3df3087 2003-12-06 devnull for(h=ht[n%NHASH]; h; h=h->next)
782 d3df3087 2003-12-06 devnull if(h->n == n)
783 d3df3087 2003-12-06 devnull return h->v;
784 d3df3087 2003-12-06 devnull return nil;
785 d3df3087 2003-12-06 devnull }
786 d3df3087 2003-12-06 devnull
787 d3df3087 2003-12-06 devnull int
788 d3df3087 2003-12-06 devnull delhash(Hash **ht, uint n, void *v)
789 d3df3087 2003-12-06 devnull {
790 d3df3087 2003-12-06 devnull Hash *h, **l;
791 d3df3087 2003-12-06 devnull
792 d3df3087 2003-12-06 devnull for(l=&ht[n%NHASH]; h=*l; l=&h->next)
793 d3df3087 2003-12-06 devnull if(h->n == n){
794 ceb04770 2003-12-09 devnull if(h->v != v){
795 ceb04770 2003-12-09 devnull if(verbose) fprint(2, "delhash %d got %p want %p\n", n, h->v, v);
796 ceb04770 2003-12-09 devnull return -1;
797 ceb04770 2003-12-09 devnull }
798 d3df3087 2003-12-06 devnull *l = h->next;
799 d3df3087 2003-12-06 devnull free(h);
800 d3df3087 2003-12-06 devnull return 0;
801 d3df3087 2003-12-06 devnull }
802 d3df3087 2003-12-06 devnull return -1;
803 d3df3087 2003-12-06 devnull }
804 d3df3087 2003-12-06 devnull
805 d3df3087 2003-12-06 devnull int
806 d3df3087 2003-12-06 devnull puthash(Hash **ht, uint n, void *v)
807 d3df3087 2003-12-06 devnull {
808 d3df3087 2003-12-06 devnull Hash *h;
809 d3df3087 2003-12-06 devnull
810 d3df3087 2003-12-06 devnull if(gethash(ht, n))
811 d3df3087 2003-12-06 devnull return -1;
812 d3df3087 2003-12-06 devnull h = emalloc(sizeof(Hash));
813 d3df3087 2003-12-06 devnull h->next = ht[n%NHASH];
814 d3df3087 2003-12-06 devnull h->n = n;
815 d3df3087 2003-12-06 devnull h->v = v;
816 d3df3087 2003-12-06 devnull ht[n%NHASH] = h;
817 d3df3087 2003-12-06 devnull return 0;
818 d3df3087 2003-12-06 devnull }
819 d3df3087 2003-12-06 devnull
820 d3df3087 2003-12-06 devnull Fid **fidtab;
821 d3df3087 2003-12-06 devnull int nfidtab;
822 d3df3087 2003-12-06 devnull Fid *freefid;
823 d3df3087 2003-12-06 devnull
824 d3df3087 2003-12-06 devnull Fid*
825 d3df3087 2003-12-06 devnull fidnew(int cfid)
826 d3df3087 2003-12-06 devnull {
827 d3df3087 2003-12-06 devnull Fid *f;
828 d3df3087 2003-12-06 devnull
829 d3df3087 2003-12-06 devnull if(freefid == nil){
830 ceb04770 2003-12-09 devnull fidtab = erealloc(fidtab, (nfidtab+1)*sizeof(fidtab[0]));
831 d3df3087 2003-12-06 devnull fidtab[nfidtab] = emalloc(sizeof(Fid));
832 ceb04770 2003-12-09 devnull freefid = fidtab[nfidtab];
833 ceb04770 2003-12-09 devnull freefid->fid = nfidtab++;
834 d3df3087 2003-12-06 devnull }
835 d3df3087 2003-12-06 devnull f = freefid;
836 d3df3087 2003-12-06 devnull freefid = f->next;
837 ceb04770 2003-12-09 devnull f->cfid = cfid;
838 d3df3087 2003-12-06 devnull f->ref = 1;
839 d3df3087 2003-12-06 devnull return f;
840 d3df3087 2003-12-06 devnull }
841 d3df3087 2003-12-06 devnull
842 d3df3087 2003-12-06 devnull void
843 d3df3087 2003-12-06 devnull fidput(Fid *f)
844 d3df3087 2003-12-06 devnull {
845 ceb04770 2003-12-09 devnull if(f == nil)
846 ceb04770 2003-12-09 devnull return;
847 d3df3087 2003-12-06 devnull assert(f->ref > 0);
848 d3df3087 2003-12-06 devnull if(--f->ref > 0)
849 d3df3087 2003-12-06 devnull return;
850 d3df3087 2003-12-06 devnull f->next = freefid;
851 d3df3087 2003-12-06 devnull f->cfid = -1;
852 d3df3087 2003-12-06 devnull freefid = f;
853 d3df3087 2003-12-06 devnull }
854 d3df3087 2003-12-06 devnull
855 d3df3087 2003-12-06 devnull Msg **msgtab;
856 d3df3087 2003-12-06 devnull int nmsgtab;
857 d3df3087 2003-12-06 devnull Msg *freemsg;
858 d3df3087 2003-12-06 devnull
859 d3df3087 2003-12-06 devnull Msg*
860 d3df3087 2003-12-06 devnull msgnew(void)
861 d3df3087 2003-12-06 devnull {
862 d3df3087 2003-12-06 devnull Msg *m;
863 d3df3087 2003-12-06 devnull
864 d3df3087 2003-12-06 devnull if(freemsg == nil){
865 ceb04770 2003-12-09 devnull msgtab = erealloc(msgtab, (nmsgtab+1)*sizeof(msgtab[0]));
866 d3df3087 2003-12-06 devnull msgtab[nmsgtab] = emalloc(sizeof(Msg));
867 ceb04770 2003-12-09 devnull freemsg = msgtab[nmsgtab];
868 ceb04770 2003-12-09 devnull freemsg->tag = nmsgtab++;
869 d3df3087 2003-12-06 devnull }
870 d3df3087 2003-12-06 devnull m = freemsg;
871 d3df3087 2003-12-06 devnull freemsg = m->next;
872 d3df3087 2003-12-06 devnull m->ref = 1;
873 d3df3087 2003-12-06 devnull return m;
874 d3df3087 2003-12-06 devnull }
875 d3df3087 2003-12-06 devnull
876 d3df3087 2003-12-06 devnull void
877 d3df3087 2003-12-06 devnull msgput(Msg *m)
878 d3df3087 2003-12-06 devnull {
879 05b7f431 2004-03-02 devnull if(m == nil)
880 05b7f431 2004-03-02 devnull return;
881 05b7f431 2004-03-02 devnull
882 ceb04770 2003-12-09 devnull if(verbose > 2) fprint(2, "msgput tag %d/%d ref %d\n", m->tag, m->ctag, m->ref);
883 d3df3087 2003-12-06 devnull assert(m->ref > 0);
884 d3df3087 2003-12-06 devnull if(--m->ref > 0)
885 d3df3087 2003-12-06 devnull return;
886 ceb04770 2003-12-09 devnull m->c->nmsg--;
887 ceb04770 2003-12-09 devnull m->c = nil;
888 05b7f431 2004-03-02 devnull msgput(m->oldm);
889 05b7f431 2004-03-02 devnull m->oldm = nil;
890 ceb04770 2003-12-09 devnull fidput(m->fid);
891 32f69c36 2003-12-11 devnull m->fid = nil;
892 ceb04770 2003-12-09 devnull fidput(m->afid);
893 ceb04770 2003-12-09 devnull m->afid = nil;
894 32f69c36 2003-12-11 devnull fidput(m->newfid);
895 ceb04770 2003-12-09 devnull m->newfid = nil;
896 32f69c36 2003-12-11 devnull free(m->tpkt);
897 ceb04770 2003-12-09 devnull m->tpkt = nil;
898 32f69c36 2003-12-11 devnull free(m->rpkt);
899 ceb04770 2003-12-09 devnull m->rpkt = nil;
900 32f69c36 2003-12-11 devnull if(m->rx.type == Ropenfd)
901 32f69c36 2003-12-11 devnull close(m->rx.unixfd);
902 32f69c36 2003-12-11 devnull m->rx.unixfd = -1;
903 32f69c36 2003-12-11 devnull m->isopenfd = 0;
904 32f69c36 2003-12-11 devnull m->internal = 0;
905 d3df3087 2003-12-06 devnull m->next = freemsg;
906 d3df3087 2003-12-06 devnull freemsg = m;
907 d3df3087 2003-12-06 devnull }
908 d3df3087 2003-12-06 devnull
909 ceb04770 2003-12-09 devnull Msg*
910 ceb04770 2003-12-09 devnull msgget(int n)
911 ceb04770 2003-12-09 devnull {
912 ceb04770 2003-12-09 devnull Msg *m;
913 ceb04770 2003-12-09 devnull
914 ceb04770 2003-12-09 devnull if(n < 0 || n >= nmsgtab)
915 ceb04770 2003-12-09 devnull return nil;
916 ceb04770 2003-12-09 devnull m = msgtab[n];
917 ceb04770 2003-12-09 devnull if(m->ref == 0)
918 ceb04770 2003-12-09 devnull return nil;
919 32f69c36 2003-12-11 devnull if(verbose) fprint(2, "msgget %d = %p\n", n, m);
920 ceb04770 2003-12-09 devnull m->ref++;
921 ceb04770 2003-12-09 devnull return m;
922 ceb04770 2003-12-09 devnull }
923 ceb04770 2003-12-09 devnull
924 ceb04770 2003-12-09 devnull
925 d3df3087 2003-12-06 devnull void*
926 d3df3087 2003-12-06 devnull emalloc(int n)
927 d3df3087 2003-12-06 devnull {
928 d3df3087 2003-12-06 devnull void *v;
929 d3df3087 2003-12-06 devnull
930 d3df3087 2003-12-06 devnull v = mallocz(n, 1);
931 ceb04770 2003-12-09 devnull if(v == nil){
932 ceb04770 2003-12-09 devnull abort();
933 ceb04770 2003-12-09 devnull sysfatal("out of memory allocating %d", n);
934 ceb04770 2003-12-09 devnull }
935 d3df3087 2003-12-06 devnull return v;
936 d3df3087 2003-12-06 devnull }
937 d3df3087 2003-12-06 devnull
938 d3df3087 2003-12-06 devnull void*
939 d3df3087 2003-12-06 devnull erealloc(void *v, int n)
940 d3df3087 2003-12-06 devnull {
941 d3df3087 2003-12-06 devnull v = realloc(v, n);
942 ceb04770 2003-12-09 devnull if(v == nil){
943 ceb04770 2003-12-09 devnull abort();
944 ceb04770 2003-12-09 devnull sysfatal("out of memory reallocating %d", n);
945 ceb04770 2003-12-09 devnull }
946 d3df3087 2003-12-06 devnull return v;
947 d3df3087 2003-12-06 devnull }
948 d3df3087 2003-12-06 devnull
949 d3df3087 2003-12-06 devnull typedef struct Qel Qel;
950 d3df3087 2003-12-06 devnull struct Qel
951 d3df3087 2003-12-06 devnull {
952 d3df3087 2003-12-06 devnull Qel *next;
953 d3df3087 2003-12-06 devnull void *p;
954 d3df3087 2003-12-06 devnull };
955 d3df3087 2003-12-06 devnull
956 d3df3087 2003-12-06 devnull struct Queue
957 d3df3087 2003-12-06 devnull {
958 d3df3087 2003-12-06 devnull int hungup;
959 d3df3087 2003-12-06 devnull QLock lk;
960 d3df3087 2003-12-06 devnull Rendez r;
961 d3df3087 2003-12-06 devnull Qel *head;
962 d3df3087 2003-12-06 devnull Qel *tail;
963 d3df3087 2003-12-06 devnull };
964 d3df3087 2003-12-06 devnull
965 d3df3087 2003-12-06 devnull Queue*
966 d3df3087 2003-12-06 devnull qalloc(void)
967 d3df3087 2003-12-06 devnull {
968 d3df3087 2003-12-06 devnull Queue *q;
969 d3df3087 2003-12-06 devnull
970 d3df3087 2003-12-06 devnull q = mallocz(sizeof(Queue), 1);
971 d3df3087 2003-12-06 devnull if(q == nil)
972 d3df3087 2003-12-06 devnull return nil;
973 d3df3087 2003-12-06 devnull q->r.l = &q->lk;
974 d3df3087 2003-12-06 devnull return q;
975 d3df3087 2003-12-06 devnull }
976 d3df3087 2003-12-06 devnull
977 d3df3087 2003-12-06 devnull int
978 d3df3087 2003-12-06 devnull sendq(Queue *q, void *p)
979 d3df3087 2003-12-06 devnull {
980 d3df3087 2003-12-06 devnull Qel *e;
981 d3df3087 2003-12-06 devnull
982 d3df3087 2003-12-06 devnull e = emalloc(sizeof(Qel));
983 d3df3087 2003-12-06 devnull qlock(&q->lk);
984 d3df3087 2003-12-06 devnull if(q->hungup){
985 d3df3087 2003-12-06 devnull werrstr("hungup queue");
986 d3df3087 2003-12-06 devnull qunlock(&q->lk);
987 d3df3087 2003-12-06 devnull return -1;
988 d3df3087 2003-12-06 devnull }
989 d3df3087 2003-12-06 devnull e->p = p;
990 d3df3087 2003-12-06 devnull e->next = nil;
991 d3df3087 2003-12-06 devnull if(q->head == nil)
992 d3df3087 2003-12-06 devnull q->head = e;
993 d3df3087 2003-12-06 devnull else
994 d3df3087 2003-12-06 devnull q->tail->next = e;
995 d3df3087 2003-12-06 devnull q->tail = e;
996 d3df3087 2003-12-06 devnull rwakeup(&q->r);
997 d3df3087 2003-12-06 devnull qunlock(&q->lk);
998 d3df3087 2003-12-06 devnull return 0;
999 d3df3087 2003-12-06 devnull }
1000 d3df3087 2003-12-06 devnull
1001 d3df3087 2003-12-06 devnull void*
1002 d3df3087 2003-12-06 devnull recvq(Queue *q)
1003 d3df3087 2003-12-06 devnull {
1004 d3df3087 2003-12-06 devnull void *p;
1005 d3df3087 2003-12-06 devnull Qel *e;
1006 d3df3087 2003-12-06 devnull
1007 d3df3087 2003-12-06 devnull qlock(&q->lk);
1008 d3df3087 2003-12-06 devnull while(q->head == nil && !q->hungup)
1009 d3df3087 2003-12-06 devnull rsleep(&q->r);
1010 d3df3087 2003-12-06 devnull if(q->hungup){
1011 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1012 d3df3087 2003-12-06 devnull return nil;
1013 d3df3087 2003-12-06 devnull }
1014 d3df3087 2003-12-06 devnull e = q->head;
1015 d3df3087 2003-12-06 devnull q->head = e->next;
1016 d3df3087 2003-12-06 devnull qunlock(&q->lk);
1017 d3df3087 2003-12-06 devnull p = e->p;
1018 d3df3087 2003-12-06 devnull free(e);
1019 d3df3087 2003-12-06 devnull return p;
1020 d3df3087 2003-12-06 devnull }
1021 ceb04770 2003-12-09 devnull
1022 ceb04770 2003-12-09 devnull uchar*
1023 ceb04770 2003-12-09 devnull read9ppkt(Ioproc *io, int fd)
1024 ceb04770 2003-12-09 devnull {
1025 ceb04770 2003-12-09 devnull uchar buf[4], *pkt;
1026 ceb04770 2003-12-09 devnull int n, nn;
1027 ceb04770 2003-12-09 devnull
1028 ceb04770 2003-12-09 devnull n = ioreadn(io, fd, buf, 4);
1029 ceb04770 2003-12-09 devnull if(n != 4)
1030 ceb04770 2003-12-09 devnull return nil;
1031 ceb04770 2003-12-09 devnull n = GBIT32(buf);
1032 ceb04770 2003-12-09 devnull pkt = emalloc(n);
1033 ceb04770 2003-12-09 devnull PBIT32(pkt, n);
1034 ceb04770 2003-12-09 devnull nn = ioreadn(io, fd, pkt+4, n-4);
1035 ceb04770 2003-12-09 devnull if(nn != n-4){
1036 ceb04770 2003-12-09 devnull free(pkt);
1037 ceb04770 2003-12-09 devnull return nil;
1038 ceb04770 2003-12-09 devnull }
1039 32f69c36 2003-12-11 devnull /* would do this if we ever got one of these, but we only generate them
1040 32f69c36 2003-12-11 devnull if(pkt[4] == Ropenfd){
1041 32f69c36 2003-12-11 devnull newfd = iorecvfd(io, fd);
1042 32f69c36 2003-12-11 devnull PBIT32(pkt+n-4, newfd);
1043 32f69c36 2003-12-11 devnull }
1044 32f69c36 2003-12-11 devnull */
1045 ceb04770 2003-12-09 devnull return pkt;
1046 ceb04770 2003-12-09 devnull }
1047 ceb04770 2003-12-09 devnull
1048 ceb04770 2003-12-09 devnull Msg*
1049 ceb04770 2003-12-09 devnull mread9p(Ioproc *io, int fd)
1050 ceb04770 2003-12-09 devnull {
1051 ceb04770 2003-12-09 devnull int n, nn;
1052 ceb04770 2003-12-09 devnull uchar *pkt;
1053 ceb04770 2003-12-09 devnull Msg *m;
1054 ceb04770 2003-12-09 devnull
1055 ceb04770 2003-12-09 devnull if((pkt = read9ppkt(io, fd)) == nil)
1056 ceb04770 2003-12-09 devnull return nil;
1057 ceb04770 2003-12-09 devnull
1058 ceb04770 2003-12-09 devnull m = msgnew();
1059 ceb04770 2003-12-09 devnull m->tpkt = pkt;
1060 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1061 ceb04770 2003-12-09 devnull nn = convM2S(pkt, n, &m->tx);
1062 ceb04770 2003-12-09 devnull if(nn != n){
1063 ceb04770 2003-12-09 devnull fprint(2, "read bad packet from %d\n", fd);
1064 ceb04770 2003-12-09 devnull return nil;
1065 ceb04770 2003-12-09 devnull }
1066 ceb04770 2003-12-09 devnull return m;
1067 ceb04770 2003-12-09 devnull }
1068 ceb04770 2003-12-09 devnull
1069 ceb04770 2003-12-09 devnull int
1070 ceb04770 2003-12-09 devnull mwrite9p(Ioproc *io, int fd, uchar *pkt)
1071 ceb04770 2003-12-09 devnull {
1072 32f69c36 2003-12-11 devnull int n, nfd;
1073 ceb04770 2003-12-09 devnull
1074 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1075 ceb04770 2003-12-09 devnull if(verbose > 2) fprint(2, "write %d %d %.*H\n", fd, n, n, pkt);
1076 ceb04770 2003-12-09 devnull if(iowrite(io, fd, pkt, n) != n){
1077 ceb04770 2003-12-09 devnull fprint(2, "write error: %r\n");
1078 ceb04770 2003-12-09 devnull return -1;
1079 ceb04770 2003-12-09 devnull }
1080 32f69c36 2003-12-11 devnull if(pkt[4] == Ropenfd){
1081 32f69c36 2003-12-11 devnull nfd = GBIT32(pkt+n-4);
1082 32f69c36 2003-12-11 devnull if(iosendfd(io, fd, nfd) < 0){
1083 32f69c36 2003-12-11 devnull fprint(2, "send fd error: %r\n");
1084 32f69c36 2003-12-11 devnull return -1;
1085 32f69c36 2003-12-11 devnull }
1086 32f69c36 2003-12-11 devnull }
1087 ceb04770 2003-12-09 devnull return 0;
1088 ceb04770 2003-12-09 devnull }
1089 ceb04770 2003-12-09 devnull
1090 ceb04770 2003-12-09 devnull void
1091 ceb04770 2003-12-09 devnull restring(uchar *pkt, int pn, char *s)
1092 ceb04770 2003-12-09 devnull {
1093 ceb04770 2003-12-09 devnull int n;
1094 ceb04770 2003-12-09 devnull
1095 ceb04770 2003-12-09 devnull if(s < (char*)pkt || s >= (char*)pkt+pn)
1096 ceb04770 2003-12-09 devnull return;
1097 ceb04770 2003-12-09 devnull
1098 ceb04770 2003-12-09 devnull n = strlen(s);
1099 ceb04770 2003-12-09 devnull memmove(s+1, s, n);
1100 ceb04770 2003-12-09 devnull PBIT16((uchar*)s-1, n);
1101 ceb04770 2003-12-09 devnull }
1102 ceb04770 2003-12-09 devnull
1103 ceb04770 2003-12-09 devnull void
1104 ceb04770 2003-12-09 devnull rewritehdr(Fcall *f, uchar *pkt)
1105 ceb04770 2003-12-09 devnull {
1106 ceb04770 2003-12-09 devnull int i, n;
1107 ceb04770 2003-12-09 devnull
1108 ceb04770 2003-12-09 devnull n = GBIT32(pkt);
1109 ceb04770 2003-12-09 devnull PBIT16(pkt+5, f->tag);
1110 ceb04770 2003-12-09 devnull switch(f->type){
1111 ceb04770 2003-12-09 devnull case Tversion:
1112 ceb04770 2003-12-09 devnull case Rversion:
1113 ceb04770 2003-12-09 devnull restring(pkt, n, f->version);
1114 ceb04770 2003-12-09 devnull break;
1115 ceb04770 2003-12-09 devnull case Tauth:
1116 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->afid);
1117 ceb04770 2003-12-09 devnull restring(pkt, n, f->uname);
1118 ceb04770 2003-12-09 devnull restring(pkt, n, f->aname);
1119 ceb04770 2003-12-09 devnull break;
1120 ceb04770 2003-12-09 devnull case Tflush:
1121 ceb04770 2003-12-09 devnull PBIT16(pkt+7, f->oldtag);
1122 ceb04770 2003-12-09 devnull break;
1123 ceb04770 2003-12-09 devnull case Tattach:
1124 ceb04770 2003-12-09 devnull restring(pkt, n, f->uname);
1125 ceb04770 2003-12-09 devnull restring(pkt, n, f->aname);
1126 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1127 ceb04770 2003-12-09 devnull PBIT32(pkt+11, f->afid);
1128 ceb04770 2003-12-09 devnull break;
1129 ceb04770 2003-12-09 devnull case Twalk:
1130 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1131 ceb04770 2003-12-09 devnull PBIT32(pkt+11, f->newfid);
1132 ceb04770 2003-12-09 devnull for(i=0; i<f->nwname; i++)
1133 ceb04770 2003-12-09 devnull restring(pkt, n, f->wname[i]);
1134 ceb04770 2003-12-09 devnull break;
1135 ceb04770 2003-12-09 devnull case Tcreate:
1136 ceb04770 2003-12-09 devnull restring(pkt, n, f->name);
1137 ceb04770 2003-12-09 devnull /* fall through */
1138 ceb04770 2003-12-09 devnull case Topen:
1139 ceb04770 2003-12-09 devnull case Tread:
1140 ceb04770 2003-12-09 devnull case Twrite:
1141 ceb04770 2003-12-09 devnull case Tclunk:
1142 ceb04770 2003-12-09 devnull case Tremove:
1143 ceb04770 2003-12-09 devnull case Tstat:
1144 ceb04770 2003-12-09 devnull case Twstat:
1145 ceb04770 2003-12-09 devnull PBIT32(pkt+7, f->fid);
1146 ceb04770 2003-12-09 devnull break;
1147 ceb04770 2003-12-09 devnull case Rerror:
1148 ceb04770 2003-12-09 devnull restring(pkt, n, f->ename);
1149 ceb04770 2003-12-09 devnull break;
1150 ceb04770 2003-12-09 devnull }
1151 ceb04770 2003-12-09 devnull }
1152 ceb04770 2003-12-09 devnull
1153 8ad51794 2004-03-25 devnull #ifdef _LIBC_H_
1154 ceb04770 2003-12-09 devnull /* unix select-based polling */
1155 32f69c36 2003-12-11 devnull struct Ioproc
1156 32f69c36 2003-12-11 devnull {
1157 32f69c36 2003-12-11 devnull Channel *c;
1158 32f69c36 2003-12-11 devnull Ioproc *next;
1159 32f69c36 2003-12-11 devnull int index;
1160 32f69c36 2003-12-11 devnull };
1161 32f69c36 2003-12-11 devnull
1162 ceb04770 2003-12-09 devnull Ioproc*
1163 ceb04770 2003-12-09 devnull ioproc(void)
1164 ceb04770 2003-12-09 devnull {
1165 5a8e63b2 2004-02-29 devnull return (Ioproc*)-1;
1166 32f69c36 2003-12-11 devnull }
1167 32f69c36 2003-12-11 devnull
1168 32f69c36 2003-12-11 devnull void
1169 32f69c36 2003-12-11 devnull closeioproc(Ioproc *io)
1170 32f69c36 2003-12-11 devnull {
1171 32f69c36 2003-12-11 devnull }
1172 32f69c36 2003-12-11 devnull
1173 ceb04770 2003-12-09 devnull long
1174 ceb04770 2003-12-09 devnull ioread(Ioproc *io, int fd, void *v, long n)
1175 ceb04770 2003-12-09 devnull {
1176 ceb04770 2003-12-09 devnull USED(io);
1177 ceb04770 2003-12-09 devnull
1178 5a8e63b2 2004-02-29 devnull return threadread(fd, v, n);
1179 ceb04770 2003-12-09 devnull }
1180 ceb04770 2003-12-09 devnull
1181 ceb04770 2003-12-09 devnull long
1182 32f69c36 2003-12-11 devnull ioreadn(Ioproc *io, int fd, void *v, long n)
1183 ceb04770 2003-12-09 devnull {
1184 32f69c36 2003-12-11 devnull long tot, m;
1185 32f69c36 2003-12-11 devnull uchar *u;
1186 32f69c36 2003-12-11 devnull
1187 32f69c36 2003-12-11 devnull u = v;
1188 32f69c36 2003-12-11 devnull for(tot=0; tot<n; tot+=m){
1189 32f69c36 2003-12-11 devnull m = ioread(io, fd, u+tot, n-tot);
1190 32f69c36 2003-12-11 devnull if(m <= 0){
1191 32f69c36 2003-12-11 devnull if(tot)
1192 32f69c36 2003-12-11 devnull break;
1193 32f69c36 2003-12-11 devnull return m;
1194 32f69c36 2003-12-11 devnull }
1195 32f69c36 2003-12-11 devnull }
1196 32f69c36 2003-12-11 devnull return tot;
1197 32f69c36 2003-12-11 devnull }
1198 32f69c36 2003-12-11 devnull
1199 32f69c36 2003-12-11 devnull int
1200 32f69c36 2003-12-11 devnull iorecvfd(Ioproc *io, int fd)
1201 32f69c36 2003-12-11 devnull {
1202 32f69c36 2003-12-11 devnull int r;
1203 32f69c36 2003-12-11 devnull
1204 5a8e63b2 2004-02-29 devnull threadfdnoblock(fd);
1205 5a8e63b2 2004-02-29 devnull while((r=recvfd(fd)) < 0){
1206 5a8e63b2 2004-02-29 devnull if(errno == EINTR)
1207 5a8e63b2 2004-02-29 devnull continue;
1208 5a8e63b2 2004-02-29 devnull if(errno == EWOULDBLOCK || errno == EAGAIN){
1209 5a8e63b2 2004-02-29 devnull threadfdwait(fd, 'r');
1210 5a8e63b2 2004-02-29 devnull continue;
1211 5a8e63b2 2004-02-29 devnull }
1212 5a8e63b2 2004-02-29 devnull break;
1213 5a8e63b2 2004-02-29 devnull }
1214 32f69c36 2003-12-11 devnull return r;
1215 32f69c36 2003-12-11 devnull }
1216 32f69c36 2003-12-11 devnull
1217 32f69c36 2003-12-11 devnull int
1218 32f69c36 2003-12-11 devnull iosendfd(Ioproc *io, int s, int fd)
1219 32f69c36 2003-12-11 devnull {
1220 32f69c36 2003-12-11 devnull int r;
1221 32f69c36 2003-12-11 devnull
1222 5a8e63b2 2004-02-29 devnull threadfdnoblock(s);
1223 5a8e63b2 2004-02-29 devnull while((r=sendfd(s, fd)) < 0){
1224 5a8e63b2 2004-02-29 devnull if(errno == EINTR)
1225 5a8e63b2 2004-02-29 devnull continue;
1226 5a8e63b2 2004-02-29 devnull if(errno == EWOULDBLOCK || errno == EAGAIN){
1227 5a8e63b2 2004-02-29 devnull threadfdwait(fd, 'w');
1228 5a8e63b2 2004-02-29 devnull continue;
1229 5a8e63b2 2004-02-29 devnull }
1230 5a8e63b2 2004-02-29 devnull break;
1231 5a8e63b2 2004-02-29 devnull }
1232 32f69c36 2003-12-11 devnull return r;
1233 32f69c36 2003-12-11 devnull }
1234 32f69c36 2003-12-11 devnull
1235 32f69c36 2003-12-11 devnull static long
1236 32f69c36 2003-12-11 devnull _iowrite(Ioproc *io, int fd, void *v, long n)
1237 32f69c36 2003-12-11 devnull {
1238 ceb04770 2003-12-09 devnull USED(io);
1239 5a8e63b2 2004-02-29 devnull return threadwrite(fd, v, n);
1240 ceb04770 2003-12-09 devnull }
1241 ceb04770 2003-12-09 devnull
1242 32f69c36 2003-12-11 devnull long
1243 32f69c36 2003-12-11 devnull iowrite(Ioproc *io, int fd, void *v, long n)
1244 32f69c36 2003-12-11 devnull {
1245 32f69c36 2003-12-11 devnull long tot, m;
1246 32f69c36 2003-12-11 devnull uchar *u;
1247 32f69c36 2003-12-11 devnull
1248 32f69c36 2003-12-11 devnull u = v;
1249 32f69c36 2003-12-11 devnull for(tot=0; tot<n; tot+=m){
1250 32f69c36 2003-12-11 devnull m = _iowrite(io, fd, u+tot, n-tot);
1251 49588d5d 2003-12-17 devnull if(m < 0){
1252 32f69c36 2003-12-11 devnull if(tot)
1253 32f69c36 2003-12-11 devnull break;
1254 32f69c36 2003-12-11 devnull return m;
1255 32f69c36 2003-12-11 devnull }
1256 32f69c36 2003-12-11 devnull }
1257 32f69c36 2003-12-11 devnull return tot;
1258 32f69c36 2003-12-11 devnull }
1259 32f69c36 2003-12-11 devnull
1260 ceb04770 2003-12-09 devnull int
1261 32f69c36 2003-12-11 devnull iolisten(Ioproc *io, char *dir, char *ndir)
1262 ceb04770 2003-12-09 devnull {
1263 32f69c36 2003-12-11 devnull int fd;
1264 32f69c36 2003-12-11 devnull int r;
1265 32f69c36 2003-12-11 devnull extern int _p9netfd(char*);
1266 ceb04770 2003-12-09 devnull USED(io);
1267 ceb04770 2003-12-09 devnull
1268 32f69c36 2003-12-11 devnull if((fd = _p9netfd(dir)) < 0)
1269 32f69c36 2003-12-11 devnull return -1;
1270 5a8e63b2 2004-02-29 devnull threadfdnoblock(fd);
1271 5a8e63b2 2004-02-29 devnull while((r=listen(dir, ndir)) < 0){
1272 5a8e63b2 2004-02-29 devnull if(errno == EINTR)
1273 5a8e63b2 2004-02-29 devnull continue;
1274 5a8e63b2 2004-02-29 devnull if(errno == EWOULDBLOCK || errno == EAGAIN){
1275 5a8e63b2 2004-02-29 devnull threadfdwait(fd, 'r');
1276 5a8e63b2 2004-02-29 devnull continue;
1277 5a8e63b2 2004-02-29 devnull }
1278 5a8e63b2 2004-02-29 devnull break;
1279 5a8e63b2 2004-02-29 devnull }
1280 32f69c36 2003-12-11 devnull return r;
1281 ceb04770 2003-12-09 devnull }
1282 ceb04770 2003-12-09 devnull
1283 ceb04770 2003-12-09 devnull int
1284 ceb04770 2003-12-09 devnull ioaccept(Ioproc *io, int fd, char *dir)
1285 ceb04770 2003-12-09 devnull {
1286 32f69c36 2003-12-11 devnull int r;
1287 ceb04770 2003-12-09 devnull USED(io);
1288 ceb04770 2003-12-09 devnull
1289 5a8e63b2 2004-02-29 devnull threadfdnoblock(fd);
1290 5a8e63b2 2004-02-29 devnull while((r=accept(fd, dir)) < 0){
1291 5a8e63b2 2004-02-29 devnull if(errno == EINTR)
1292 5a8e63b2 2004-02-29 devnull continue;
1293 5a8e63b2 2004-02-29 devnull if(errno == EWOULDBLOCK || errno == EAGAIN){
1294 5a8e63b2 2004-02-29 devnull threadfdwait(fd, 'r');
1295 5a8e63b2 2004-02-29 devnull continue;
1296 5a8e63b2 2004-02-29 devnull }
1297 5a8e63b2 2004-02-29 devnull break;
1298 5a8e63b2 2004-02-29 devnull }
1299 32f69c36 2003-12-11 devnull return r;
1300 ceb04770 2003-12-09 devnull }
1301 ceb04770 2003-12-09 devnull
1302 ceb04770 2003-12-09 devnull #else
1303 ceb04770 2003-12-09 devnull /* real plan 9 io procs */
1304 ceb04770 2003-12-09 devnull static long
1305 ceb04770 2003-12-09 devnull _iolisten(va_list *arg)
1306 ceb04770 2003-12-09 devnull {
1307 ceb04770 2003-12-09 devnull char *a, *b;
1308 ceb04770 2003-12-09 devnull
1309 ceb04770 2003-12-09 devnull a = va_arg(*arg, char*);
1310 ceb04770 2003-12-09 devnull b = va_arg(*arg, char*);
1311 ceb04770 2003-12-09 devnull return listen(a, b);
1312 ceb04770 2003-12-09 devnull }
1313 ceb04770 2003-12-09 devnull
1314 ceb04770 2003-12-09 devnull int
1315 ceb04770 2003-12-09 devnull iolisten(Ioproc *io, char *a, char *b)
1316 ceb04770 2003-12-09 devnull {
1317 ceb04770 2003-12-09 devnull return iocall(io, _iolisten, a, b);
1318 ceb04770 2003-12-09 devnull }
1319 ceb04770 2003-12-09 devnull
1320 ceb04770 2003-12-09 devnull static long
1321 ceb04770 2003-12-09 devnull _ioaccept(va_list *arg)
1322 ceb04770 2003-12-09 devnull {
1323 ceb04770 2003-12-09 devnull int fd;
1324 ceb04770 2003-12-09 devnull char *dir;
1325 ceb04770 2003-12-09 devnull
1326 ceb04770 2003-12-09 devnull fd = va_arg(*arg, int);
1327 ceb04770 2003-12-09 devnull dir = va_arg(*arg, char*);
1328 ceb04770 2003-12-09 devnull return accept(fd, dir);
1329 ceb04770 2003-12-09 devnull }
1330 ceb04770 2003-12-09 devnull
1331 ceb04770 2003-12-09 devnull int
1332 ceb04770 2003-12-09 devnull ioaccept(Ioproc *io, int fd, char *dir)
1333 ceb04770 2003-12-09 devnull {
1334 ceb04770 2003-12-09 devnull return iocall(io, _ioaccept, fd, dir);
1335 ceb04770 2003-12-09 devnull }
1336 ceb04770 2003-12-09 devnull #endif