static char * rwalk1(Fid *fid, char *name, Qid *qid) { Xfile *f=xfile(fid, Asis); int nr, sinbr = 0; chat("walk1(fid=%d,name=\"%s\")...", fid->fid, name); errno = 0; if( !f ){ chat("no xfile..."); goto error; } if( !(fid->qid.type & QTDIR) ){ chat("qid.type=0x%x...", fid->qid.type); goto error; } sinbr = f->pinbr; if( name == 0 || name[0] == 0 || !strcmp(name, ".") ){ *qid = fid->qid; goto ok; }else if( !strcmp(name, "..") ){ if( fid->qid.path == f->xf->rootqid.path ){ chat("walkup from root..."); *qid = fid->qid; goto ok; } if( get_inode(f, f->pinbr) < 0 ) goto error; if( f->pinbr == EXT2_ROOT_INODE ){ *qid = f->xf->rootqid; f->pinbr = EXT2_ROOT_INODE; } else { *qid = (Qid){f->pinbr,0,QTDIR}; f->inbr = f->pinbr; if( (nr = get_file(f, "..")) < 0 ) goto error; f->pinbr = nr; } }else{ f->pinbr = f->inbr; if( (nr = get_file(f, name)) < 0 ) goto error; if( get_inode(f, nr) < 0 ) goto error; *qid = (Qid){nr,0,0}; if( nr == EXT2_ROOT_INODE ) *qid = f->xf->rootqid; else if( S_ISDIR(getmode(f)) ) qid->type = QTDIR; /*strcpy(f->name, thdr.name);*/ } ok: chat("OK\n"); return 0; error: f->pinbr = sinbr; chat("%s\n", xerrstr(Enonexist)); return xerrstr(Enonexist); }
static char * rclone(Fid *fid, Fid *newfid) { Xfile *of = xfile(fid, Asis); Xfile *nf = xfile(newfid, Clean); chat("clone(fid=%d,newfid=%d)...", fid->fid, newfid->fid); errno = 0; if(!of) errno = Eio; else if(!nf) errno = Enomem; else{ Xfile *next = nf->next; *nf = *of; nf->next = next; nf->fid = newfid->fid; nf->root = 0; } chat("%s\n", errno? xerrstr(errno) : "OK"); return errno ? xerrstr(errno) : 0; }
void io(int srvfd) { int n, pid; pid = getpid(); fmtinstall('F', fcallfmt); for(;;){ /* * reading from a pipe or a network device * will give an error after a few eof reads. * however, we cannot tell the difference * between a zero-length read and an interrupt * on the processes writing to us, * so we wait for the error. */ n = read9pmsg(srvfd, mdata, sizeof mdata); if(n < 0) break; if(n == 0) continue; if(convM2S(mdata, n, req) == 0) continue; if(chatty) fprint(2, "dossrv %d:<-%F\n", pid, req); errno = 0; if(!fcalls[req->type]) errno = Ebadfcall; else (*fcalls[req->type])(); if(errno){ rep->type = Rerror; rep->ename = xerrstr(errno); }else{ rep->type = req->type + 1; rep->fid = req->fid; } rep->tag = req->tag; if(chatty) fprint(2, "dossrv %d:->%F\n", pid, rep); n = convS2M(rep, mdata, sizeof mdata); if(n == 0) panic("convS2M error on write"); if(write(srvfd, mdata, n) != n) panic("mount write"); } chat("server shut down"); }
static void response(Req *r) { char *err; if (errno) { err = xerrstr(errno); chat("%s\n", err); respond(r, err); } else { chat("OK\n"); respond(r, nil); } }