123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- #include "all.h"
- static int
- readmsg(Chan *c, void *abuf, int n, int *ninep)
- {
- int fd, len;
- uchar *buf;
- buf = abuf;
- fd = c->chan;
- qlock(&c->rlock);
- if(readn(fd, buf, 3) != 3){
- qunlock(&c->rlock);
- print("readn(3) fails: %r\n");
- return -1;
- }
- if((50 <= buf[0] && buf[0] <= 87 && (buf[0]&1)==0 && GBIT16(buf+1) == 0xFFFF)
- || buf[0] == 86 /* Tattach */){
- *ninep = 1;
- /* assume message boundaries */
- n = read(fd, buf+3, n-3);
- if(n < 0){
- qunlock(&c->rlock);
- return -1;
- }
- return n+3;
- }
- *ninep = 2;
- if(read(fd, buf+3, 1) != 1){
- qunlock(&c->rlock);
- print("read(1) fails: %r\n");
- return -1;
- }
- len = GBIT32(buf);
- if(len > n){
- print("msg too large\n");
- qunlock(&c->rlock);
- return -1;
- }
- if(readn(fd, buf+4, len-4) != len-4){
- print("readn(%d) fails: %r\n", len-4);
- qunlock(&c->rlock);
- return -1;
- }
- qunlock(&c->rlock);
- return len;
- }
- int
- startserveproc(void (*f)(Chan*, uchar*, int), char *name, Chan *c, uchar *b, int nb)
- {
- int pid;
- switch(pid = rfork(RFMEM|RFPROC)){
- case -1:
- panic("can't fork");
- case 0:
- break;
- default:
- return pid;
- }
- procname = name;
- f(c, b, nb);
- _exits(nil);
- return -1; /* can't happen */
- }
- void
- serve(Chan *chan)
- {
- int i, nin, p9, npid;
- uchar inbuf[1024];
- void (*s)(Chan*, uchar*, int);
- int *pid;
- Waitmsg *w;
- p9 = 0;
- if((nin = readmsg(chan, inbuf, sizeof inbuf, &p9)) < 0)
- return;
- switch(p9){
- default:
- print("unknown 9P type\n");
- return;
- case 1:
- s = serve9p1;
- break;
- case 2:
- s = serve9p2;
- break;
- }
- pid = malloc(sizeof(pid)*(conf.nserve-1));
- if(pid == nil)
- return;
- for(i=1; i<conf.nserve; i++)
- pid[i-1] = startserveproc(s, "srv", chan, nil, 0);
- (*s)(chan, inbuf, nin);
- /* wait till all other servers for this chan are done */
- for(npid = conf.nserve-1; npid > 0;){
- w = wait();
- if(w == 0)
- break;
- for(i = 0; i < conf.nserve-1; i++)
- if(pid[i] == w->pid)
- npid--;
- free(w);
- }
- free(pid);
- }
|