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