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