1*8ccd4a63SDavid du Colombier #include "u.h" 2*8ccd4a63SDavid du Colombier #include "lib.h" 3*8ccd4a63SDavid du Colombier #include "dat.h" 4*8ccd4a63SDavid du Colombier #include "fns.h" 5*8ccd4a63SDavid du Colombier #include "error.h" 6*8ccd4a63SDavid du Colombier 7*8ccd4a63SDavid du Colombier #include "user.h" 8*8ccd4a63SDavid du Colombier #undef open 9*8ccd4a63SDavid du Colombier #undef mount 10*8ccd4a63SDavid du Colombier #undef read 11*8ccd4a63SDavid du Colombier #undef write 12*8ccd4a63SDavid du Colombier #undef seek 13*8ccd4a63SDavid du Colombier #undef stat 14*8ccd4a63SDavid du Colombier #undef wstat 15*8ccd4a63SDavid du Colombier #undef remove 16*8ccd4a63SDavid du Colombier #undef close 17*8ccd4a63SDavid du Colombier #undef fstat 18*8ccd4a63SDavid du Colombier #undef fwstat 19*8ccd4a63SDavid du Colombier 20*8ccd4a63SDavid du Colombier /* 21*8ccd4a63SDavid du Colombier * The sys*() routines needn't poperror() as they return directly to syscall(). 22*8ccd4a63SDavid du Colombier */ 23*8ccd4a63SDavid du Colombier 24*8ccd4a63SDavid du Colombier static void 25*8ccd4a63SDavid du Colombier unlockfgrp(Fgrp *f) 26*8ccd4a63SDavid du Colombier { 27*8ccd4a63SDavid du Colombier int ex; 28*8ccd4a63SDavid du Colombier 29*8ccd4a63SDavid du Colombier ex = f->exceed; 30*8ccd4a63SDavid du Colombier f->exceed = 0; 31*8ccd4a63SDavid du Colombier unlock(&f->ref.lk); 32*8ccd4a63SDavid du Colombier if(ex) 33*8ccd4a63SDavid du Colombier pprint("warning: process exceeds %d file descriptors\n", ex); 34*8ccd4a63SDavid du Colombier } 35*8ccd4a63SDavid du Colombier 36*8ccd4a63SDavid du Colombier int 37*8ccd4a63SDavid du Colombier growfd(Fgrp *f, int fd) /* fd is always >= 0 */ 38*8ccd4a63SDavid du Colombier { 39*8ccd4a63SDavid du Colombier Chan **newfd, **oldfd; 40*8ccd4a63SDavid du Colombier 41*8ccd4a63SDavid du Colombier if(fd < f->nfd) 42*8ccd4a63SDavid du Colombier return 0; 43*8ccd4a63SDavid du Colombier if(fd >= f->nfd+DELTAFD) 44*8ccd4a63SDavid du Colombier return -1; /* out of range */ 45*8ccd4a63SDavid du Colombier /* 46*8ccd4a63SDavid du Colombier * Unbounded allocation is unwise; besides, there are only 16 bits 47*8ccd4a63SDavid du Colombier * of fid in 9P 48*8ccd4a63SDavid du Colombier */ 49*8ccd4a63SDavid du Colombier if(f->nfd >= 5000){ 50*8ccd4a63SDavid du Colombier Exhausted: 51*8ccd4a63SDavid du Colombier print("no free file descriptors\n"); 52*8ccd4a63SDavid du Colombier return -1; 53*8ccd4a63SDavid du Colombier } 54*8ccd4a63SDavid du Colombier newfd = malloc((f->nfd+DELTAFD)*sizeof(Chan*)); 55*8ccd4a63SDavid du Colombier if(newfd == 0) 56*8ccd4a63SDavid du Colombier goto Exhausted; 57*8ccd4a63SDavid du Colombier oldfd = f->fd; 58*8ccd4a63SDavid du Colombier memmove(newfd, oldfd, f->nfd*sizeof(Chan*)); 59*8ccd4a63SDavid du Colombier f->fd = newfd; 60*8ccd4a63SDavid du Colombier free(oldfd); 61*8ccd4a63SDavid du Colombier f->nfd += DELTAFD; 62*8ccd4a63SDavid du Colombier if(fd > f->maxfd){ 63*8ccd4a63SDavid du Colombier if(fd/100 > f->maxfd/100) 64*8ccd4a63SDavid du Colombier f->exceed = (fd/100)*100; 65*8ccd4a63SDavid du Colombier f->maxfd = fd; 66*8ccd4a63SDavid du Colombier } 67*8ccd4a63SDavid du Colombier return 1; 68*8ccd4a63SDavid du Colombier } 69*8ccd4a63SDavid du Colombier 70*8ccd4a63SDavid du Colombier /* 71*8ccd4a63SDavid du Colombier * this assumes that the fgrp is locked 72*8ccd4a63SDavid du Colombier */ 73*8ccd4a63SDavid du Colombier int 74*8ccd4a63SDavid du Colombier findfreefd(Fgrp *f, int start) 75*8ccd4a63SDavid du Colombier { 76*8ccd4a63SDavid du Colombier int fd; 77*8ccd4a63SDavid du Colombier 78*8ccd4a63SDavid du Colombier for(fd=start; fd<f->nfd; fd++) 79*8ccd4a63SDavid du Colombier if(f->fd[fd] == 0) 80*8ccd4a63SDavid du Colombier break; 81*8ccd4a63SDavid du Colombier if(fd >= f->nfd && growfd(f, fd) < 0) 82*8ccd4a63SDavid du Colombier return -1; 83*8ccd4a63SDavid du Colombier return fd; 84*8ccd4a63SDavid du Colombier } 85*8ccd4a63SDavid du Colombier 86*8ccd4a63SDavid du Colombier int 87*8ccd4a63SDavid du Colombier newfd(Chan *c) 88*8ccd4a63SDavid du Colombier { 89*8ccd4a63SDavid du Colombier int fd; 90*8ccd4a63SDavid du Colombier Fgrp *f; 91*8ccd4a63SDavid du Colombier 92*8ccd4a63SDavid du Colombier f = up->fgrp; 93*8ccd4a63SDavid du Colombier lock(&f->ref.lk); 94*8ccd4a63SDavid du Colombier fd = findfreefd(f, 0); 95*8ccd4a63SDavid du Colombier if(fd < 0){ 96*8ccd4a63SDavid du Colombier unlockfgrp(f); 97*8ccd4a63SDavid du Colombier return -1; 98*8ccd4a63SDavid du Colombier } 99*8ccd4a63SDavid du Colombier if(fd > f->maxfd) 100*8ccd4a63SDavid du Colombier f->maxfd = fd; 101*8ccd4a63SDavid du Colombier f->fd[fd] = c; 102*8ccd4a63SDavid du Colombier unlockfgrp(f); 103*8ccd4a63SDavid du Colombier return fd; 104*8ccd4a63SDavid du Colombier } 105*8ccd4a63SDavid du Colombier 106*8ccd4a63SDavid du Colombier int 107*8ccd4a63SDavid du Colombier newfd2(int fd[2], Chan *c[2]) 108*8ccd4a63SDavid du Colombier { 109*8ccd4a63SDavid du Colombier Fgrp *f; 110*8ccd4a63SDavid du Colombier 111*8ccd4a63SDavid du Colombier f = up->fgrp; 112*8ccd4a63SDavid du Colombier lock(&f->ref.lk); 113*8ccd4a63SDavid du Colombier fd[0] = findfreefd(f, 0); 114*8ccd4a63SDavid du Colombier if(fd[0] < 0){ 115*8ccd4a63SDavid du Colombier unlockfgrp(f); 116*8ccd4a63SDavid du Colombier return -1; 117*8ccd4a63SDavid du Colombier } 118*8ccd4a63SDavid du Colombier fd[1] = findfreefd(f, fd[0]+1); 119*8ccd4a63SDavid du Colombier if(fd[1] < 0){ 120*8ccd4a63SDavid du Colombier unlockfgrp(f); 121*8ccd4a63SDavid du Colombier return -1; 122*8ccd4a63SDavid du Colombier } 123*8ccd4a63SDavid du Colombier if(fd[1] > f->maxfd) 124*8ccd4a63SDavid du Colombier f->maxfd = fd[1]; 125*8ccd4a63SDavid du Colombier f->fd[fd[0]] = c[0]; 126*8ccd4a63SDavid du Colombier f->fd[fd[1]] = c[1]; 127*8ccd4a63SDavid du Colombier unlockfgrp(f); 128*8ccd4a63SDavid du Colombier 129*8ccd4a63SDavid du Colombier return 0; 130*8ccd4a63SDavid du Colombier } 131*8ccd4a63SDavid du Colombier 132*8ccd4a63SDavid du Colombier Chan* 133*8ccd4a63SDavid du Colombier fdtochan(int fd, int mode, int chkmnt, int iref) 134*8ccd4a63SDavid du Colombier { 135*8ccd4a63SDavid du Colombier Chan *c; 136*8ccd4a63SDavid du Colombier Fgrp *f; 137*8ccd4a63SDavid du Colombier 138*8ccd4a63SDavid du Colombier c = 0; 139*8ccd4a63SDavid du Colombier f = up->fgrp; 140*8ccd4a63SDavid du Colombier 141*8ccd4a63SDavid du Colombier lock(&f->ref.lk); 142*8ccd4a63SDavid du Colombier if(fd<0 || f->nfd<=fd || (c = f->fd[fd])==0) { 143*8ccd4a63SDavid du Colombier unlock(&f->ref.lk); 144*8ccd4a63SDavid du Colombier error(Ebadfd); 145*8ccd4a63SDavid du Colombier } 146*8ccd4a63SDavid du Colombier if(iref) 147*8ccd4a63SDavid du Colombier incref(&c->ref); 148*8ccd4a63SDavid du Colombier unlock(&f->ref.lk); 149*8ccd4a63SDavid du Colombier 150*8ccd4a63SDavid du Colombier if(chkmnt && (c->flag&CMSG)) { 151*8ccd4a63SDavid du Colombier if(iref) 152*8ccd4a63SDavid du Colombier cclose(c); 153*8ccd4a63SDavid du Colombier error(Ebadusefd); 154*8ccd4a63SDavid du Colombier } 155*8ccd4a63SDavid du Colombier 156*8ccd4a63SDavid du Colombier if(mode<0 || c->mode==ORDWR) 157*8ccd4a63SDavid du Colombier return c; 158*8ccd4a63SDavid du Colombier 159*8ccd4a63SDavid du Colombier if((mode&OTRUNC) && c->mode==OREAD) { 160*8ccd4a63SDavid du Colombier if(iref) 161*8ccd4a63SDavid du Colombier cclose(c); 162*8ccd4a63SDavid du Colombier error(Ebadusefd); 163*8ccd4a63SDavid du Colombier } 164*8ccd4a63SDavid du Colombier 165*8ccd4a63SDavid du Colombier if((mode&~OTRUNC) != c->mode) { 166*8ccd4a63SDavid du Colombier if(iref) 167*8ccd4a63SDavid du Colombier cclose(c); 168*8ccd4a63SDavid du Colombier error(Ebadusefd); 169*8ccd4a63SDavid du Colombier } 170*8ccd4a63SDavid du Colombier 171*8ccd4a63SDavid du Colombier return c; 172*8ccd4a63SDavid du Colombier } 173*8ccd4a63SDavid du Colombier 174*8ccd4a63SDavid du Colombier int 175*8ccd4a63SDavid du Colombier openmode(ulong o) 176*8ccd4a63SDavid du Colombier { 177*8ccd4a63SDavid du Colombier o &= ~(OTRUNC|OCEXEC|ORCLOSE); 178*8ccd4a63SDavid du Colombier if(o > OEXEC) 179*8ccd4a63SDavid du Colombier error(Ebadarg); 180*8ccd4a63SDavid du Colombier if(o == OEXEC) 181*8ccd4a63SDavid du Colombier return OREAD; 182*8ccd4a63SDavid du Colombier return o; 183*8ccd4a63SDavid du Colombier } 184*8ccd4a63SDavid du Colombier 185*8ccd4a63SDavid du Colombier long 186*8ccd4a63SDavid du Colombier _sysfd2path(int fd, char *buf, uint nbuf) 187*8ccd4a63SDavid du Colombier { 188*8ccd4a63SDavid du Colombier Chan *c; 189*8ccd4a63SDavid du Colombier 190*8ccd4a63SDavid du Colombier c = fdtochan(fd, -1, 0, 1); 191*8ccd4a63SDavid du Colombier 192*8ccd4a63SDavid du Colombier if(c->name == nil) 193*8ccd4a63SDavid du Colombier snprint(buf, nbuf, "<null>"); 194*8ccd4a63SDavid du Colombier else 195*8ccd4a63SDavid du Colombier snprint(buf, nbuf, "%s", c->name->s); 196*8ccd4a63SDavid du Colombier cclose(c); 197*8ccd4a63SDavid du Colombier return 0; 198*8ccd4a63SDavid du Colombier } 199*8ccd4a63SDavid du Colombier 200*8ccd4a63SDavid du Colombier long 201*8ccd4a63SDavid du Colombier _syspipe(int fd[2]) 202*8ccd4a63SDavid du Colombier { 203*8ccd4a63SDavid du Colombier Chan *c[2]; 204*8ccd4a63SDavid du Colombier Dev *d; 205*8ccd4a63SDavid du Colombier static char *datastr[] = {"data", "data1"}; 206*8ccd4a63SDavid du Colombier 207*8ccd4a63SDavid du Colombier d = devtab[devno('|', 0)]; 208*8ccd4a63SDavid du Colombier c[0] = namec("#|", Atodir, 0, 0); 209*8ccd4a63SDavid du Colombier c[1] = 0; 210*8ccd4a63SDavid du Colombier fd[0] = -1; 211*8ccd4a63SDavid du Colombier fd[1] = -1; 212*8ccd4a63SDavid du Colombier 213*8ccd4a63SDavid du Colombier if(waserror()){ 214*8ccd4a63SDavid du Colombier cclose(c[0]); 215*8ccd4a63SDavid du Colombier if(c[1]) 216*8ccd4a63SDavid du Colombier cclose(c[1]); 217*8ccd4a63SDavid du Colombier nexterror(); 218*8ccd4a63SDavid du Colombier } 219*8ccd4a63SDavid du Colombier c[1] = cclone(c[0]); 220*8ccd4a63SDavid du Colombier if(walk(&c[0], datastr+0, 1, 1, nil) < 0) 221*8ccd4a63SDavid du Colombier error(Egreg); 222*8ccd4a63SDavid du Colombier if(walk(&c[1], datastr+1, 1, 1, nil) < 0) 223*8ccd4a63SDavid du Colombier error(Egreg); 224*8ccd4a63SDavid du Colombier c[0] = d->open(c[0], ORDWR); 225*8ccd4a63SDavid du Colombier c[1] = d->open(c[1], ORDWR); 226*8ccd4a63SDavid du Colombier if(newfd2(fd, c) < 0) 227*8ccd4a63SDavid du Colombier error(Enofd); 228*8ccd4a63SDavid du Colombier poperror(); 229*8ccd4a63SDavid du Colombier 230*8ccd4a63SDavid du Colombier return 0; 231*8ccd4a63SDavid du Colombier } 232*8ccd4a63SDavid du Colombier 233*8ccd4a63SDavid du Colombier long 234*8ccd4a63SDavid du Colombier _sysdup(int fd0, int fd1) 235*8ccd4a63SDavid du Colombier { 236*8ccd4a63SDavid du Colombier int fd; 237*8ccd4a63SDavid du Colombier Chan *c, *oc; 238*8ccd4a63SDavid du Colombier Fgrp *f = up->fgrp; 239*8ccd4a63SDavid du Colombier 240*8ccd4a63SDavid du Colombier /* 241*8ccd4a63SDavid du Colombier * Close after dup'ing, so date > #d/1 works 242*8ccd4a63SDavid du Colombier */ 243*8ccd4a63SDavid du Colombier c = fdtochan(fd0, -1, 0, 1); 244*8ccd4a63SDavid du Colombier fd = fd1; 245*8ccd4a63SDavid du Colombier if(fd != -1){ 246*8ccd4a63SDavid du Colombier lock(&f->ref.lk); 247*8ccd4a63SDavid du Colombier if(fd<0 || growfd(f, fd)<0) { 248*8ccd4a63SDavid du Colombier unlockfgrp(f); 249*8ccd4a63SDavid du Colombier cclose(c); 250*8ccd4a63SDavid du Colombier error(Ebadfd); 251*8ccd4a63SDavid du Colombier } 252*8ccd4a63SDavid du Colombier if(fd > f->maxfd) 253*8ccd4a63SDavid du Colombier f->maxfd = fd; 254*8ccd4a63SDavid du Colombier 255*8ccd4a63SDavid du Colombier oc = f->fd[fd]; 256*8ccd4a63SDavid du Colombier f->fd[fd] = c; 257*8ccd4a63SDavid du Colombier unlockfgrp(f); 258*8ccd4a63SDavid du Colombier if(oc) 259*8ccd4a63SDavid du Colombier cclose(oc); 260*8ccd4a63SDavid du Colombier }else{ 261*8ccd4a63SDavid du Colombier if(waserror()) { 262*8ccd4a63SDavid du Colombier cclose(c); 263*8ccd4a63SDavid du Colombier nexterror(); 264*8ccd4a63SDavid du Colombier } 265*8ccd4a63SDavid du Colombier fd = newfd(c); 266*8ccd4a63SDavid du Colombier if(fd < 0) 267*8ccd4a63SDavid du Colombier error(Enofd); 268*8ccd4a63SDavid du Colombier poperror(); 269*8ccd4a63SDavid du Colombier } 270*8ccd4a63SDavid du Colombier 271*8ccd4a63SDavid du Colombier return fd; 272*8ccd4a63SDavid du Colombier } 273*8ccd4a63SDavid du Colombier 274*8ccd4a63SDavid du Colombier long 275*8ccd4a63SDavid du Colombier _sysopen(char *name, int mode) 276*8ccd4a63SDavid du Colombier { 277*8ccd4a63SDavid du Colombier int fd; 278*8ccd4a63SDavid du Colombier Chan *c = 0; 279*8ccd4a63SDavid du Colombier 280*8ccd4a63SDavid du Colombier openmode(mode); /* error check only */ 281*8ccd4a63SDavid du Colombier if(waserror()){ 282*8ccd4a63SDavid du Colombier if(c) 283*8ccd4a63SDavid du Colombier cclose(c); 284*8ccd4a63SDavid du Colombier nexterror(); 285*8ccd4a63SDavid du Colombier } 286*8ccd4a63SDavid du Colombier c = namec(name, Aopen, mode, 0); 287*8ccd4a63SDavid du Colombier fd = newfd(c); 288*8ccd4a63SDavid du Colombier if(fd < 0) 289*8ccd4a63SDavid du Colombier error(Enofd); 290*8ccd4a63SDavid du Colombier poperror(); 291*8ccd4a63SDavid du Colombier return fd; 292*8ccd4a63SDavid du Colombier } 293*8ccd4a63SDavid du Colombier 294*8ccd4a63SDavid du Colombier void 295*8ccd4a63SDavid du Colombier fdclose(int fd, int flag) 296*8ccd4a63SDavid du Colombier { 297*8ccd4a63SDavid du Colombier int i; 298*8ccd4a63SDavid du Colombier Chan *c; 299*8ccd4a63SDavid du Colombier Fgrp *f = up->fgrp; 300*8ccd4a63SDavid du Colombier 301*8ccd4a63SDavid du Colombier lock(&f->ref.lk); 302*8ccd4a63SDavid du Colombier c = f->fd[fd]; 303*8ccd4a63SDavid du Colombier if(c == 0){ 304*8ccd4a63SDavid du Colombier /* can happen for users with shared fd tables */ 305*8ccd4a63SDavid du Colombier unlock(&f->ref.lk); 306*8ccd4a63SDavid du Colombier return; 307*8ccd4a63SDavid du Colombier } 308*8ccd4a63SDavid du Colombier if(flag){ 309*8ccd4a63SDavid du Colombier if(c==0 || !(c->flag&flag)){ 310*8ccd4a63SDavid du Colombier unlock(&f->ref.lk); 311*8ccd4a63SDavid du Colombier return; 312*8ccd4a63SDavid du Colombier } 313*8ccd4a63SDavid du Colombier } 314*8ccd4a63SDavid du Colombier f->fd[fd] = 0; 315*8ccd4a63SDavid du Colombier if(fd == f->maxfd) 316*8ccd4a63SDavid du Colombier for(i=fd; --i>=0 && f->fd[i]==0; ) 317*8ccd4a63SDavid du Colombier f->maxfd = i; 318*8ccd4a63SDavid du Colombier 319*8ccd4a63SDavid du Colombier unlock(&f->ref.lk); 320*8ccd4a63SDavid du Colombier cclose(c); 321*8ccd4a63SDavid du Colombier } 322*8ccd4a63SDavid du Colombier 323*8ccd4a63SDavid du Colombier long 324*8ccd4a63SDavid du Colombier _sysclose(int fd) 325*8ccd4a63SDavid du Colombier { 326*8ccd4a63SDavid du Colombier fdtochan(fd, -1, 0, 0); 327*8ccd4a63SDavid du Colombier fdclose(fd, 0); 328*8ccd4a63SDavid du Colombier 329*8ccd4a63SDavid du Colombier return 0; 330*8ccd4a63SDavid du Colombier } 331*8ccd4a63SDavid du Colombier 332*8ccd4a63SDavid du Colombier long 333*8ccd4a63SDavid du Colombier unionread(Chan *c, void *va, long n) 334*8ccd4a63SDavid du Colombier { 335*8ccd4a63SDavid du Colombier int i; 336*8ccd4a63SDavid du Colombier long nr; 337*8ccd4a63SDavid du Colombier Mhead *m; 338*8ccd4a63SDavid du Colombier Mount *mount; 339*8ccd4a63SDavid du Colombier 340*8ccd4a63SDavid du Colombier qlock(&c->umqlock); 341*8ccd4a63SDavid du Colombier m = c->umh; 342*8ccd4a63SDavid du Colombier rlock(&m->lock); 343*8ccd4a63SDavid du Colombier mount = m->mount; 344*8ccd4a63SDavid du Colombier /* bring mount in sync with c->uri and c->umc */ 345*8ccd4a63SDavid du Colombier for(i = 0; mount != nil && i < c->uri; i++) 346*8ccd4a63SDavid du Colombier mount = mount->next; 347*8ccd4a63SDavid du Colombier 348*8ccd4a63SDavid du Colombier nr = 0; 349*8ccd4a63SDavid du Colombier while(mount != nil) { 350*8ccd4a63SDavid du Colombier /* Error causes component of union to be skipped */ 351*8ccd4a63SDavid du Colombier if(mount->to && !waserror()) { 352*8ccd4a63SDavid du Colombier if(c->umc == nil){ 353*8ccd4a63SDavid du Colombier c->umc = cclone(mount->to); 354*8ccd4a63SDavid du Colombier c->umc = devtab[c->umc->type]->open(c->umc, OREAD); 355*8ccd4a63SDavid du Colombier } 356*8ccd4a63SDavid du Colombier 357*8ccd4a63SDavid du Colombier nr = devtab[c->umc->type]->read(c->umc, va, n, c->umc->offset); 358*8ccd4a63SDavid du Colombier c->umc->offset += nr; 359*8ccd4a63SDavid du Colombier poperror(); 360*8ccd4a63SDavid du Colombier } 361*8ccd4a63SDavid du Colombier if(nr > 0) 362*8ccd4a63SDavid du Colombier break; 363*8ccd4a63SDavid du Colombier 364*8ccd4a63SDavid du Colombier /* Advance to next element */ 365*8ccd4a63SDavid du Colombier c->uri++; 366*8ccd4a63SDavid du Colombier if(c->umc) { 367*8ccd4a63SDavid du Colombier cclose(c->umc); 368*8ccd4a63SDavid du Colombier c->umc = nil; 369*8ccd4a63SDavid du Colombier } 370*8ccd4a63SDavid du Colombier mount = mount->next; 371*8ccd4a63SDavid du Colombier } 372*8ccd4a63SDavid du Colombier runlock(&m->lock); 373*8ccd4a63SDavid du Colombier qunlock(&c->umqlock); 374*8ccd4a63SDavid du Colombier return nr; 375*8ccd4a63SDavid du Colombier } 376*8ccd4a63SDavid du Colombier 377*8ccd4a63SDavid du Colombier static long 378*8ccd4a63SDavid du Colombier kread(int fd, void *buf, long n, vlong *offp) 379*8ccd4a63SDavid du Colombier { 380*8ccd4a63SDavid du Colombier int dir; 381*8ccd4a63SDavid du Colombier Chan *c; 382*8ccd4a63SDavid du Colombier vlong off; 383*8ccd4a63SDavid du Colombier 384*8ccd4a63SDavid du Colombier c = fdtochan(fd, OREAD, 1, 1); 385*8ccd4a63SDavid du Colombier 386*8ccd4a63SDavid du Colombier if(waserror()) { 387*8ccd4a63SDavid du Colombier cclose(c); 388*8ccd4a63SDavid du Colombier nexterror(); 389*8ccd4a63SDavid du Colombier } 390*8ccd4a63SDavid du Colombier 391*8ccd4a63SDavid du Colombier dir = c->qid.type&QTDIR; 392*8ccd4a63SDavid du Colombier /* 393*8ccd4a63SDavid du Colombier * The offset is passed through on directories, normally. sysseek complains but 394*8ccd4a63SDavid du Colombier * pread is used by servers and e.g. exportfs that shouldn't need to worry about this issue. 395*8ccd4a63SDavid du Colombier */ 396*8ccd4a63SDavid du Colombier 397*8ccd4a63SDavid du Colombier if(offp == nil) /* use and maintain channel's offset */ 398*8ccd4a63SDavid du Colombier off = c->offset; 399*8ccd4a63SDavid du Colombier else 400*8ccd4a63SDavid du Colombier off = *offp; 401*8ccd4a63SDavid du Colombier 402*8ccd4a63SDavid du Colombier if(off < 0) 403*8ccd4a63SDavid du Colombier error(Enegoff); 404*8ccd4a63SDavid du Colombier 405*8ccd4a63SDavid du Colombier if(dir && c->umh) 406*8ccd4a63SDavid du Colombier n = unionread(c, buf, n); 407*8ccd4a63SDavid du Colombier else 408*8ccd4a63SDavid du Colombier n = devtab[c->type]->read(c, buf, n, off); 409*8ccd4a63SDavid du Colombier 410*8ccd4a63SDavid du Colombier if(offp == nil){ 411*8ccd4a63SDavid du Colombier lock(&c->ref.lk); 412*8ccd4a63SDavid du Colombier c->offset += n; 413*8ccd4a63SDavid du Colombier unlock(&c->ref.lk); 414*8ccd4a63SDavid du Colombier } 415*8ccd4a63SDavid du Colombier 416*8ccd4a63SDavid du Colombier poperror(); 417*8ccd4a63SDavid du Colombier cclose(c); 418*8ccd4a63SDavid du Colombier 419*8ccd4a63SDavid du Colombier return n; 420*8ccd4a63SDavid du Colombier } 421*8ccd4a63SDavid du Colombier 422*8ccd4a63SDavid du Colombier /* name conflicts with netbsd 423*8ccd4a63SDavid du Colombier long 424*8ccd4a63SDavid du Colombier _sys_read(int fd, void *buf, long n) 425*8ccd4a63SDavid du Colombier { 426*8ccd4a63SDavid du Colombier return kread(fd, buf, n, nil); 427*8ccd4a63SDavid du Colombier } 428*8ccd4a63SDavid du Colombier */ 429*8ccd4a63SDavid du Colombier 430*8ccd4a63SDavid du Colombier long 431*8ccd4a63SDavid du Colombier _syspread(int fd, void *buf, long n, vlong off) 432*8ccd4a63SDavid du Colombier { 433*8ccd4a63SDavid du Colombier if(off == ((uvlong) ~0)) 434*8ccd4a63SDavid du Colombier return kread(fd, buf, n, nil); 435*8ccd4a63SDavid du Colombier return kread(fd, buf, n, &off); 436*8ccd4a63SDavid du Colombier } 437*8ccd4a63SDavid du Colombier 438*8ccd4a63SDavid du Colombier static long 439*8ccd4a63SDavid du Colombier kwrite(int fd, void *buf, long nn, vlong *offp) 440*8ccd4a63SDavid du Colombier { 441*8ccd4a63SDavid du Colombier Chan *c; 442*8ccd4a63SDavid du Colombier long m, n; 443*8ccd4a63SDavid du Colombier vlong off; 444*8ccd4a63SDavid du Colombier 445*8ccd4a63SDavid du Colombier n = 0; 446*8ccd4a63SDavid du Colombier c = fdtochan(fd, OWRITE, 1, 1); 447*8ccd4a63SDavid du Colombier if(waserror()) { 448*8ccd4a63SDavid du Colombier if(offp == nil){ 449*8ccd4a63SDavid du Colombier lock(&c->ref.lk); 450*8ccd4a63SDavid du Colombier c->offset -= n; 451*8ccd4a63SDavid du Colombier unlock(&c->ref.lk); 452*8ccd4a63SDavid du Colombier } 453*8ccd4a63SDavid du Colombier cclose(c); 454*8ccd4a63SDavid du Colombier nexterror(); 455*8ccd4a63SDavid du Colombier } 456*8ccd4a63SDavid du Colombier 457*8ccd4a63SDavid du Colombier if(c->qid.type & QTDIR) 458*8ccd4a63SDavid du Colombier error(Eisdir); 459*8ccd4a63SDavid du Colombier 460*8ccd4a63SDavid du Colombier n = nn; 461*8ccd4a63SDavid du Colombier 462*8ccd4a63SDavid du Colombier if(offp == nil){ /* use and maintain channel's offset */ 463*8ccd4a63SDavid du Colombier lock(&c->ref.lk); 464*8ccd4a63SDavid du Colombier off = c->offset; 465*8ccd4a63SDavid du Colombier c->offset += n; 466*8ccd4a63SDavid du Colombier unlock(&c->ref.lk); 467*8ccd4a63SDavid du Colombier }else 468*8ccd4a63SDavid du Colombier off = *offp; 469*8ccd4a63SDavid du Colombier 470*8ccd4a63SDavid du Colombier if(off < 0) 471*8ccd4a63SDavid du Colombier error(Enegoff); 472*8ccd4a63SDavid du Colombier 473*8ccd4a63SDavid du Colombier m = devtab[c->type]->write(c, buf, n, off); 474*8ccd4a63SDavid du Colombier 475*8ccd4a63SDavid du Colombier if(offp == nil && m < n){ 476*8ccd4a63SDavid du Colombier lock(&c->ref.lk); 477*8ccd4a63SDavid du Colombier c->offset -= n - m; 478*8ccd4a63SDavid du Colombier unlock(&c->ref.lk); 479*8ccd4a63SDavid du Colombier } 480*8ccd4a63SDavid du Colombier 481*8ccd4a63SDavid du Colombier poperror(); 482*8ccd4a63SDavid du Colombier cclose(c); 483*8ccd4a63SDavid du Colombier 484*8ccd4a63SDavid du Colombier return m; 485*8ccd4a63SDavid du Colombier } 486*8ccd4a63SDavid du Colombier 487*8ccd4a63SDavid du Colombier long 488*8ccd4a63SDavid du Colombier sys_write(int fd, void *buf, long n) 489*8ccd4a63SDavid du Colombier { 490*8ccd4a63SDavid du Colombier return kwrite(fd, buf, n, nil); 491*8ccd4a63SDavid du Colombier } 492*8ccd4a63SDavid du Colombier 493*8ccd4a63SDavid du Colombier long 494*8ccd4a63SDavid du Colombier _syspwrite(int fd, void *buf, long n, vlong off) 495*8ccd4a63SDavid du Colombier { 496*8ccd4a63SDavid du Colombier if(off == ((uvlong) ~0)) 497*8ccd4a63SDavid du Colombier return kwrite(fd, buf, n, nil); 498*8ccd4a63SDavid du Colombier return kwrite(fd, buf, n, &off); 499*8ccd4a63SDavid du Colombier } 500*8ccd4a63SDavid du Colombier 501*8ccd4a63SDavid du Colombier static vlong 502*8ccd4a63SDavid du Colombier _sysseek(int fd, vlong off, int whence) 503*8ccd4a63SDavid du Colombier { 504*8ccd4a63SDavid du Colombier Chan *c; 505*8ccd4a63SDavid du Colombier uchar buf[sizeof(Dir)+100]; 506*8ccd4a63SDavid du Colombier Dir dir; 507*8ccd4a63SDavid du Colombier int n; 508*8ccd4a63SDavid du Colombier 509*8ccd4a63SDavid du Colombier c = fdtochan(fd, -1, 1, 1); 510*8ccd4a63SDavid du Colombier if(waserror()){ 511*8ccd4a63SDavid du Colombier cclose(c); 512*8ccd4a63SDavid du Colombier nexterror(); 513*8ccd4a63SDavid du Colombier } 514*8ccd4a63SDavid du Colombier if(devtab[c->type]->dc == '|') 515*8ccd4a63SDavid du Colombier error(Eisstream); 516*8ccd4a63SDavid du Colombier 517*8ccd4a63SDavid du Colombier switch(whence){ 518*8ccd4a63SDavid du Colombier case 0: 519*8ccd4a63SDavid du Colombier if((c->qid.type & QTDIR) && off != 0) 520*8ccd4a63SDavid du Colombier error(Eisdir); 521*8ccd4a63SDavid du Colombier if(off < 0) 522*8ccd4a63SDavid du Colombier error(Enegoff); 523*8ccd4a63SDavid du Colombier c->offset = off; 524*8ccd4a63SDavid du Colombier break; 525*8ccd4a63SDavid du Colombier 526*8ccd4a63SDavid du Colombier case 1: 527*8ccd4a63SDavid du Colombier if(c->qid.type & QTDIR) 528*8ccd4a63SDavid du Colombier error(Eisdir); 529*8ccd4a63SDavid du Colombier lock(&c->ref.lk); /* lock for read/write update */ 530*8ccd4a63SDavid du Colombier off = off + c->offset; 531*8ccd4a63SDavid du Colombier if(off < 0) 532*8ccd4a63SDavid du Colombier error(Enegoff); 533*8ccd4a63SDavid du Colombier c->offset = off; 534*8ccd4a63SDavid du Colombier unlock(&c->ref.lk); 535*8ccd4a63SDavid du Colombier break; 536*8ccd4a63SDavid du Colombier 537*8ccd4a63SDavid du Colombier case 2: 538*8ccd4a63SDavid du Colombier if(c->qid.type & QTDIR) 539*8ccd4a63SDavid du Colombier error(Eisdir); 540*8ccd4a63SDavid du Colombier n = devtab[c->type]->stat(c, buf, sizeof buf); 541*8ccd4a63SDavid du Colombier if(convM2D(buf, n, &dir, nil) == 0) 542*8ccd4a63SDavid du Colombier error("internal error: stat error in seek"); 543*8ccd4a63SDavid du Colombier off = dir.length + off; 544*8ccd4a63SDavid du Colombier if(off < 0) 545*8ccd4a63SDavid du Colombier error(Enegoff); 546*8ccd4a63SDavid du Colombier c->offset = off; 547*8ccd4a63SDavid du Colombier break; 548*8ccd4a63SDavid du Colombier 549*8ccd4a63SDavid du Colombier default: 550*8ccd4a63SDavid du Colombier error(Ebadarg); 551*8ccd4a63SDavid du Colombier } 552*8ccd4a63SDavid du Colombier c->uri = 0; 553*8ccd4a63SDavid du Colombier c->dri = 0; 554*8ccd4a63SDavid du Colombier cclose(c); 555*8ccd4a63SDavid du Colombier poperror(); 556*8ccd4a63SDavid du Colombier return off; 557*8ccd4a63SDavid du Colombier } 558*8ccd4a63SDavid du Colombier 559*8ccd4a63SDavid du Colombier void 560*8ccd4a63SDavid du Colombier validstat(uchar *s, int n) 561*8ccd4a63SDavid du Colombier { 562*8ccd4a63SDavid du Colombier int m; 563*8ccd4a63SDavid du Colombier char buf[64]; 564*8ccd4a63SDavid du Colombier 565*8ccd4a63SDavid du Colombier if(statcheck(s, n) < 0) 566*8ccd4a63SDavid du Colombier error(Ebadstat); 567*8ccd4a63SDavid du Colombier /* verify that name entry is acceptable */ 568*8ccd4a63SDavid du Colombier s += STATFIXLEN - 4*BIT16SZ; /* location of first string */ 569*8ccd4a63SDavid du Colombier /* 570*8ccd4a63SDavid du Colombier * s now points at count for first string. 571*8ccd4a63SDavid du Colombier * if it's too long, let the server decide; this is 572*8ccd4a63SDavid du Colombier * only for his protection anyway. otherwise 573*8ccd4a63SDavid du Colombier * we'd have to allocate and waserror. 574*8ccd4a63SDavid du Colombier */ 575*8ccd4a63SDavid du Colombier m = GBIT16(s); 576*8ccd4a63SDavid du Colombier s += BIT16SZ; 577*8ccd4a63SDavid du Colombier if(m+1 > sizeof buf) 578*8ccd4a63SDavid du Colombier return; 579*8ccd4a63SDavid du Colombier memmove(buf, s, m); 580*8ccd4a63SDavid du Colombier buf[m] = '\0'; 581*8ccd4a63SDavid du Colombier /* name could be '/' */ 582*8ccd4a63SDavid du Colombier if(strcmp(buf, "/") != 0) 583*8ccd4a63SDavid du Colombier validname(buf, 0); 584*8ccd4a63SDavid du Colombier } 585*8ccd4a63SDavid du Colombier 586*8ccd4a63SDavid du Colombier long 587*8ccd4a63SDavid du Colombier _sysfstat(int fd, void *buf, long n) 588*8ccd4a63SDavid du Colombier { 589*8ccd4a63SDavid du Colombier Chan *c; 590*8ccd4a63SDavid du Colombier uint l; 591*8ccd4a63SDavid du Colombier 592*8ccd4a63SDavid du Colombier l = n; 593*8ccd4a63SDavid du Colombier validaddr(buf, l, 1); 594*8ccd4a63SDavid du Colombier c = fdtochan(fd, -1, 0, 1); 595*8ccd4a63SDavid du Colombier if(waserror()) { 596*8ccd4a63SDavid du Colombier cclose(c); 597*8ccd4a63SDavid du Colombier nexterror(); 598*8ccd4a63SDavid du Colombier } 599*8ccd4a63SDavid du Colombier l = devtab[c->type]->stat(c, buf, l); 600*8ccd4a63SDavid du Colombier poperror(); 601*8ccd4a63SDavid du Colombier cclose(c); 602*8ccd4a63SDavid du Colombier return l; 603*8ccd4a63SDavid du Colombier } 604*8ccd4a63SDavid du Colombier 605*8ccd4a63SDavid du Colombier long 606*8ccd4a63SDavid du Colombier _sysstat(char *name, void *buf, long n) 607*8ccd4a63SDavid du Colombier { 608*8ccd4a63SDavid du Colombier Chan *c; 609*8ccd4a63SDavid du Colombier uint l; 610*8ccd4a63SDavid du Colombier 611*8ccd4a63SDavid du Colombier l = n; 612*8ccd4a63SDavid du Colombier validaddr(buf, l, 1); 613*8ccd4a63SDavid du Colombier validaddr(name, 1, 0); 614*8ccd4a63SDavid du Colombier c = namec(name, Aaccess, 0, 0); 615*8ccd4a63SDavid du Colombier if(waserror()){ 616*8ccd4a63SDavid du Colombier cclose(c); 617*8ccd4a63SDavid du Colombier nexterror(); 618*8ccd4a63SDavid du Colombier } 619*8ccd4a63SDavid du Colombier l = devtab[c->type]->stat(c, buf, l); 620*8ccd4a63SDavid du Colombier poperror(); 621*8ccd4a63SDavid du Colombier cclose(c); 622*8ccd4a63SDavid du Colombier return l; 623*8ccd4a63SDavid du Colombier } 624*8ccd4a63SDavid du Colombier 625*8ccd4a63SDavid du Colombier long 626*8ccd4a63SDavid du Colombier _syschdir(char *name) 627*8ccd4a63SDavid du Colombier { 628*8ccd4a63SDavid du Colombier Chan *c; 629*8ccd4a63SDavid du Colombier 630*8ccd4a63SDavid du Colombier validaddr(name, 1, 0); 631*8ccd4a63SDavid du Colombier 632*8ccd4a63SDavid du Colombier c = namec(name, Atodir, 0, 0); 633*8ccd4a63SDavid du Colombier cclose(up->dot); 634*8ccd4a63SDavid du Colombier up->dot = c; 635*8ccd4a63SDavid du Colombier return 0; 636*8ccd4a63SDavid du Colombier } 637*8ccd4a63SDavid du Colombier 638*8ccd4a63SDavid du Colombier long 639*8ccd4a63SDavid du Colombier bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec) 640*8ccd4a63SDavid du Colombier { 641*8ccd4a63SDavid du Colombier int ret; 642*8ccd4a63SDavid du Colombier Chan *c0, *c1, *ac, *bc; 643*8ccd4a63SDavid du Colombier struct{ 644*8ccd4a63SDavid du Colombier Chan *chan; 645*8ccd4a63SDavid du Colombier Chan *authchan; 646*8ccd4a63SDavid du Colombier char *spec; 647*8ccd4a63SDavid du Colombier int flags; 648*8ccd4a63SDavid du Colombier }bogus; 649*8ccd4a63SDavid du Colombier 650*8ccd4a63SDavid du Colombier if((flag&~MMASK) || (flag&MORDER)==(MBEFORE|MAFTER)) 651*8ccd4a63SDavid du Colombier error(Ebadarg); 652*8ccd4a63SDavid du Colombier 653*8ccd4a63SDavid du Colombier bogus.flags = flag & MCACHE; 654*8ccd4a63SDavid du Colombier 655*8ccd4a63SDavid du Colombier if(ismount){ 656*8ccd4a63SDavid du Colombier if(up->pgrp->noattach) 657*8ccd4a63SDavid du Colombier error(Enoattach); 658*8ccd4a63SDavid du Colombier 659*8ccd4a63SDavid du Colombier ac = nil; 660*8ccd4a63SDavid du Colombier bc = fdtochan(fd, ORDWR, 0, 1); 661*8ccd4a63SDavid du Colombier if(waserror()) { 662*8ccd4a63SDavid du Colombier if(ac) 663*8ccd4a63SDavid du Colombier cclose(ac); 664*8ccd4a63SDavid du Colombier cclose(bc); 665*8ccd4a63SDavid du Colombier nexterror(); 666*8ccd4a63SDavid du Colombier } 667*8ccd4a63SDavid du Colombier 668*8ccd4a63SDavid du Colombier if(afd >= 0) 669*8ccd4a63SDavid du Colombier ac = fdtochan(afd, ORDWR, 0, 1); 670*8ccd4a63SDavid du Colombier 671*8ccd4a63SDavid du Colombier bogus.chan = bc; 672*8ccd4a63SDavid du Colombier bogus.authchan = ac; 673*8ccd4a63SDavid du Colombier 674*8ccd4a63SDavid du Colombier validaddr((ulong)spec, 1, 0); 675*8ccd4a63SDavid du Colombier bogus.spec = spec; 676*8ccd4a63SDavid du Colombier if(waserror()) 677*8ccd4a63SDavid du Colombier error(Ebadspec); 678*8ccd4a63SDavid du Colombier validname(spec, 1); 679*8ccd4a63SDavid du Colombier poperror(); 680*8ccd4a63SDavid du Colombier 681*8ccd4a63SDavid du Colombier ret = devno('M', 0); 682*8ccd4a63SDavid du Colombier c0 = devtab[ret]->attach((char*)&bogus); 683*8ccd4a63SDavid du Colombier 684*8ccd4a63SDavid du Colombier poperror(); 685*8ccd4a63SDavid du Colombier if(ac) 686*8ccd4a63SDavid du Colombier cclose(ac); 687*8ccd4a63SDavid du Colombier cclose(bc); 688*8ccd4a63SDavid du Colombier }else{ 689*8ccd4a63SDavid du Colombier bogus.spec = 0; 690*8ccd4a63SDavid du Colombier validaddr((ulong)arg0, 1, 0); 691*8ccd4a63SDavid du Colombier c0 = namec(arg0, Abind, 0, 0); 692*8ccd4a63SDavid du Colombier } 693*8ccd4a63SDavid du Colombier 694*8ccd4a63SDavid du Colombier if(waserror()){ 695*8ccd4a63SDavid du Colombier cclose(c0); 696*8ccd4a63SDavid du Colombier nexterror(); 697*8ccd4a63SDavid du Colombier } 698*8ccd4a63SDavid du Colombier 699*8ccd4a63SDavid du Colombier validaddr((ulong)arg1, 1, 0); 700*8ccd4a63SDavid du Colombier c1 = namec(arg1, Amount, 0, 0); 701*8ccd4a63SDavid du Colombier if(waserror()){ 702*8ccd4a63SDavid du Colombier cclose(c1); 703*8ccd4a63SDavid du Colombier nexterror(); 704*8ccd4a63SDavid du Colombier } 705*8ccd4a63SDavid du Colombier 706*8ccd4a63SDavid du Colombier ret = cmount(&c0, c1, flag, bogus.spec); 707*8ccd4a63SDavid du Colombier 708*8ccd4a63SDavid du Colombier poperror(); 709*8ccd4a63SDavid du Colombier cclose(c1); 710*8ccd4a63SDavid du Colombier poperror(); 711*8ccd4a63SDavid du Colombier cclose(c0); 712*8ccd4a63SDavid du Colombier if(ismount) 713*8ccd4a63SDavid du Colombier fdclose(fd, 0); 714*8ccd4a63SDavid du Colombier 715*8ccd4a63SDavid du Colombier return ret; 716*8ccd4a63SDavid du Colombier } 717*8ccd4a63SDavid du Colombier 718*8ccd4a63SDavid du Colombier long 719*8ccd4a63SDavid du Colombier _sysbind(char *old, char *new, int flag) 720*8ccd4a63SDavid du Colombier { 721*8ccd4a63SDavid du Colombier return bindmount(0, -1, -1, old, new, flag, nil); 722*8ccd4a63SDavid du Colombier } 723*8ccd4a63SDavid du Colombier 724*8ccd4a63SDavid du Colombier long 725*8ccd4a63SDavid du Colombier _sysmount(int fd, int afd, char *new, int flag, char *spec) 726*8ccd4a63SDavid du Colombier { 727*8ccd4a63SDavid du Colombier return bindmount(1, fd, afd, nil, new, flag, spec); 728*8ccd4a63SDavid du Colombier } 729*8ccd4a63SDavid du Colombier 730*8ccd4a63SDavid du Colombier long 731*8ccd4a63SDavid du Colombier _sysunmount(char *old, char *new) 732*8ccd4a63SDavid du Colombier { 733*8ccd4a63SDavid du Colombier Chan *cmount, *cmounted; 734*8ccd4a63SDavid du Colombier 735*8ccd4a63SDavid du Colombier cmounted = 0; 736*8ccd4a63SDavid du Colombier 737*8ccd4a63SDavid du Colombier cmount = namec(new, Amount, 0, 0); 738*8ccd4a63SDavid du Colombier 739*8ccd4a63SDavid du Colombier if(old) { 740*8ccd4a63SDavid du Colombier if(waserror()) { 741*8ccd4a63SDavid du Colombier cclose(cmount); 742*8ccd4a63SDavid du Colombier nexterror(); 743*8ccd4a63SDavid du Colombier } 744*8ccd4a63SDavid du Colombier validaddr(old, 1, 0); 745*8ccd4a63SDavid du Colombier /* 746*8ccd4a63SDavid du Colombier * This has to be namec(..., Aopen, ...) because 747*8ccd4a63SDavid du Colombier * if arg[0] is something like /srv/cs or /fd/0, 748*8ccd4a63SDavid du Colombier * opening it is the only way to get at the real 749*8ccd4a63SDavid du Colombier * Chan underneath. 750*8ccd4a63SDavid du Colombier */ 751*8ccd4a63SDavid du Colombier cmounted = namec(old, Aopen, OREAD, 0); 752*8ccd4a63SDavid du Colombier poperror(); 753*8ccd4a63SDavid du Colombier } 754*8ccd4a63SDavid du Colombier 755*8ccd4a63SDavid du Colombier if(waserror()) { 756*8ccd4a63SDavid du Colombier cclose(cmount); 757*8ccd4a63SDavid du Colombier if(cmounted) 758*8ccd4a63SDavid du Colombier cclose(cmounted); 759*8ccd4a63SDavid du Colombier nexterror(); 760*8ccd4a63SDavid du Colombier } 761*8ccd4a63SDavid du Colombier 762*8ccd4a63SDavid du Colombier cunmount(cmount, cmounted); 763*8ccd4a63SDavid du Colombier cclose(cmount); 764*8ccd4a63SDavid du Colombier if(cmounted) 765*8ccd4a63SDavid du Colombier cclose(cmounted); 766*8ccd4a63SDavid du Colombier poperror(); 767*8ccd4a63SDavid du Colombier return 0; 768*8ccd4a63SDavid du Colombier } 769*8ccd4a63SDavid du Colombier 770*8ccd4a63SDavid du Colombier long 771*8ccd4a63SDavid du Colombier _syscreate(char *name, int mode, ulong perm) 772*8ccd4a63SDavid du Colombier { 773*8ccd4a63SDavid du Colombier int fd; 774*8ccd4a63SDavid du Colombier Chan *c = 0; 775*8ccd4a63SDavid du Colombier 776*8ccd4a63SDavid du Colombier openmode(mode&~OEXCL); /* error check only; OEXCL okay here */ 777*8ccd4a63SDavid du Colombier if(waserror()) { 778*8ccd4a63SDavid du Colombier if(c) 779*8ccd4a63SDavid du Colombier cclose(c); 780*8ccd4a63SDavid du Colombier nexterror(); 781*8ccd4a63SDavid du Colombier } 782*8ccd4a63SDavid du Colombier validaddr(name, 1, 0); 783*8ccd4a63SDavid du Colombier c = namec(name, Acreate, mode, perm); 784*8ccd4a63SDavid du Colombier fd = newfd(c); 785*8ccd4a63SDavid du Colombier if(fd < 0) 786*8ccd4a63SDavid du Colombier error(Enofd); 787*8ccd4a63SDavid du Colombier poperror(); 788*8ccd4a63SDavid du Colombier return fd; 789*8ccd4a63SDavid du Colombier } 790*8ccd4a63SDavid du Colombier 791*8ccd4a63SDavid du Colombier long 792*8ccd4a63SDavid du Colombier _sysremove(char *name) 793*8ccd4a63SDavid du Colombier { 794*8ccd4a63SDavid du Colombier Chan *c; 795*8ccd4a63SDavid du Colombier 796*8ccd4a63SDavid du Colombier c = namec(name, Aremove, 0, 0); 797*8ccd4a63SDavid du Colombier if(waserror()){ 798*8ccd4a63SDavid du Colombier c->type = 0; /* see below */ 799*8ccd4a63SDavid du Colombier cclose(c); 800*8ccd4a63SDavid du Colombier nexterror(); 801*8ccd4a63SDavid du Colombier } 802*8ccd4a63SDavid du Colombier devtab[c->type]->remove(c); 803*8ccd4a63SDavid du Colombier /* 804*8ccd4a63SDavid du Colombier * Remove clunks the fid, but we need to recover the Chan 805*8ccd4a63SDavid du Colombier * so fake it up. rootclose() is known to be a nop. 806*8ccd4a63SDavid du Colombier */ 807*8ccd4a63SDavid du Colombier c->type = 0; 808*8ccd4a63SDavid du Colombier poperror(); 809*8ccd4a63SDavid du Colombier cclose(c); 810*8ccd4a63SDavid du Colombier return 0; 811*8ccd4a63SDavid du Colombier } 812*8ccd4a63SDavid du Colombier 813*8ccd4a63SDavid du Colombier long 814*8ccd4a63SDavid du Colombier _syswstat(char *name, void *buf, long n) 815*8ccd4a63SDavid du Colombier { 816*8ccd4a63SDavid du Colombier Chan *c; 817*8ccd4a63SDavid du Colombier uint l; 818*8ccd4a63SDavid du Colombier 819*8ccd4a63SDavid du Colombier l = n; 820*8ccd4a63SDavid du Colombier validstat(buf, l); 821*8ccd4a63SDavid du Colombier validaddr(name, 1, 0); 822*8ccd4a63SDavid du Colombier c = namec(name, Aaccess, 0, 0); 823*8ccd4a63SDavid du Colombier if(waserror()){ 824*8ccd4a63SDavid du Colombier cclose(c); 825*8ccd4a63SDavid du Colombier nexterror(); 826*8ccd4a63SDavid du Colombier } 827*8ccd4a63SDavid du Colombier l = devtab[c->type]->wstat(c, buf, l); 828*8ccd4a63SDavid du Colombier poperror(); 829*8ccd4a63SDavid du Colombier cclose(c); 830*8ccd4a63SDavid du Colombier return l; 831*8ccd4a63SDavid du Colombier } 832*8ccd4a63SDavid du Colombier 833*8ccd4a63SDavid du Colombier long 834*8ccd4a63SDavid du Colombier _sysfwstat(int fd, void *buf, long n) 835*8ccd4a63SDavid du Colombier { 836*8ccd4a63SDavid du Colombier Chan *c; 837*8ccd4a63SDavid du Colombier uint l; 838*8ccd4a63SDavid du Colombier 839*8ccd4a63SDavid du Colombier l = n; 840*8ccd4a63SDavid du Colombier validaddr(buf, l, 0); 841*8ccd4a63SDavid du Colombier validstat(buf, l); 842*8ccd4a63SDavid du Colombier c = fdtochan(fd, -1, 1, 1); 843*8ccd4a63SDavid du Colombier if(waserror()) { 844*8ccd4a63SDavid du Colombier cclose(c); 845*8ccd4a63SDavid du Colombier nexterror(); 846*8ccd4a63SDavid du Colombier } 847*8ccd4a63SDavid du Colombier l = devtab[c->type]->wstat(c, buf, l); 848*8ccd4a63SDavid du Colombier poperror(); 849*8ccd4a63SDavid du Colombier cclose(c); 850*8ccd4a63SDavid du Colombier return l; 851*8ccd4a63SDavid du Colombier } 852*8ccd4a63SDavid du Colombier 853*8ccd4a63SDavid du Colombier 854*8ccd4a63SDavid du Colombier static void 855*8ccd4a63SDavid du Colombier starterror(void) 856*8ccd4a63SDavid du Colombier { 857*8ccd4a63SDavid du Colombier assert(up->nerrlab == 0); 858*8ccd4a63SDavid du Colombier } 859*8ccd4a63SDavid du Colombier 860*8ccd4a63SDavid du Colombier static void 861*8ccd4a63SDavid du Colombier _syserror(void) 862*8ccd4a63SDavid du Colombier { 863*8ccd4a63SDavid du Colombier char *p; 864*8ccd4a63SDavid du Colombier 865*8ccd4a63SDavid du Colombier p = up->syserrstr; 866*8ccd4a63SDavid du Colombier up->syserrstr = up->errstr; 867*8ccd4a63SDavid du Colombier up->errstr = p; 868*8ccd4a63SDavid du Colombier } 869*8ccd4a63SDavid du Colombier 870*8ccd4a63SDavid du Colombier static void 871*8ccd4a63SDavid du Colombier enderror(void) 872*8ccd4a63SDavid du Colombier { 873*8ccd4a63SDavid du Colombier assert(up->nerrlab == 1); 874*8ccd4a63SDavid du Colombier poperror(); 875*8ccd4a63SDavid du Colombier } 876*8ccd4a63SDavid du Colombier 877*8ccd4a63SDavid du Colombier int 878*8ccd4a63SDavid du Colombier sysbind(char *old, char *new, int flag) 879*8ccd4a63SDavid du Colombier { 880*8ccd4a63SDavid du Colombier int n; 881*8ccd4a63SDavid du Colombier 882*8ccd4a63SDavid du Colombier starterror(); 883*8ccd4a63SDavid du Colombier if(waserror()){ 884*8ccd4a63SDavid du Colombier _syserror(); 885*8ccd4a63SDavid du Colombier return -1; 886*8ccd4a63SDavid du Colombier } 887*8ccd4a63SDavid du Colombier n = _sysbind(old, new, flag); 888*8ccd4a63SDavid du Colombier enderror(); 889*8ccd4a63SDavid du Colombier return n; 890*8ccd4a63SDavid du Colombier } 891*8ccd4a63SDavid du Colombier 892*8ccd4a63SDavid du Colombier int 893*8ccd4a63SDavid du Colombier syschdir(char *path) 894*8ccd4a63SDavid du Colombier { 895*8ccd4a63SDavid du Colombier int n; 896*8ccd4a63SDavid du Colombier 897*8ccd4a63SDavid du Colombier starterror(); 898*8ccd4a63SDavid du Colombier if(waserror()){ 899*8ccd4a63SDavid du Colombier _syserror(); 900*8ccd4a63SDavid du Colombier return -1; 901*8ccd4a63SDavid du Colombier } 902*8ccd4a63SDavid du Colombier n = _syschdir(path); 903*8ccd4a63SDavid du Colombier enderror(); 904*8ccd4a63SDavid du Colombier return n; 905*8ccd4a63SDavid du Colombier } 906*8ccd4a63SDavid du Colombier 907*8ccd4a63SDavid du Colombier int 908*8ccd4a63SDavid du Colombier sysclose(int fd) 909*8ccd4a63SDavid du Colombier { 910*8ccd4a63SDavid du Colombier int n; 911*8ccd4a63SDavid du Colombier 912*8ccd4a63SDavid du Colombier starterror(); 913*8ccd4a63SDavid du Colombier if(waserror()){ 914*8ccd4a63SDavid du Colombier _syserror(); 915*8ccd4a63SDavid du Colombier return -1; 916*8ccd4a63SDavid du Colombier } 917*8ccd4a63SDavid du Colombier n = _sysclose(fd); 918*8ccd4a63SDavid du Colombier enderror(); 919*8ccd4a63SDavid du Colombier return n; 920*8ccd4a63SDavid du Colombier } 921*8ccd4a63SDavid du Colombier 922*8ccd4a63SDavid du Colombier int 923*8ccd4a63SDavid du Colombier syscreate(char *name, int mode, ulong perm) 924*8ccd4a63SDavid du Colombier { 925*8ccd4a63SDavid du Colombier int n; 926*8ccd4a63SDavid du Colombier 927*8ccd4a63SDavid du Colombier starterror(); 928*8ccd4a63SDavid du Colombier if(waserror()){ 929*8ccd4a63SDavid du Colombier _syserror(); 930*8ccd4a63SDavid du Colombier return -1; 931*8ccd4a63SDavid du Colombier } 932*8ccd4a63SDavid du Colombier n = _syscreate(name, mode, perm); 933*8ccd4a63SDavid du Colombier enderror(); 934*8ccd4a63SDavid du Colombier return n; 935*8ccd4a63SDavid du Colombier } 936*8ccd4a63SDavid du Colombier 937*8ccd4a63SDavid du Colombier int 938*8ccd4a63SDavid du Colombier sysdup(int fd0, int fd1) 939*8ccd4a63SDavid du Colombier { 940*8ccd4a63SDavid du Colombier int n; 941*8ccd4a63SDavid du Colombier 942*8ccd4a63SDavid du Colombier starterror(); 943*8ccd4a63SDavid du Colombier if(waserror()){ 944*8ccd4a63SDavid du Colombier _syserror(); 945*8ccd4a63SDavid du Colombier return -1; 946*8ccd4a63SDavid du Colombier } 947*8ccd4a63SDavid du Colombier n = _sysdup(fd0, fd1); 948*8ccd4a63SDavid du Colombier enderror(); 949*8ccd4a63SDavid du Colombier return n; 950*8ccd4a63SDavid du Colombier } 951*8ccd4a63SDavid du Colombier 952*8ccd4a63SDavid du Colombier int 953*8ccd4a63SDavid du Colombier sysfstat(int fd, uchar *buf, int n) 954*8ccd4a63SDavid du Colombier { 955*8ccd4a63SDavid du Colombier starterror(); 956*8ccd4a63SDavid du Colombier if(waserror()){ 957*8ccd4a63SDavid du Colombier _syserror(); 958*8ccd4a63SDavid du Colombier return -1; 959*8ccd4a63SDavid du Colombier } 960*8ccd4a63SDavid du Colombier n = _sysfstat(fd, buf, n); 961*8ccd4a63SDavid du Colombier enderror(); 962*8ccd4a63SDavid du Colombier return n; 963*8ccd4a63SDavid du Colombier } 964*8ccd4a63SDavid du Colombier 965*8ccd4a63SDavid du Colombier int 966*8ccd4a63SDavid du Colombier sysfwstat(int fd, uchar *buf, int n) 967*8ccd4a63SDavid du Colombier { 968*8ccd4a63SDavid du Colombier starterror(); 969*8ccd4a63SDavid du Colombier if(waserror()){ 970*8ccd4a63SDavid du Colombier _syserror(); 971*8ccd4a63SDavid du Colombier return -1; 972*8ccd4a63SDavid du Colombier } 973*8ccd4a63SDavid du Colombier n = _sysfwstat(fd, buf, n); 974*8ccd4a63SDavid du Colombier enderror(); 975*8ccd4a63SDavid du Colombier return n; 976*8ccd4a63SDavid du Colombier } 977*8ccd4a63SDavid du Colombier 978*8ccd4a63SDavid du Colombier int 979*8ccd4a63SDavid du Colombier sysmount(int fd, int afd, char *new, int flag, char *spec) 980*8ccd4a63SDavid du Colombier { 981*8ccd4a63SDavid du Colombier int n; 982*8ccd4a63SDavid du Colombier 983*8ccd4a63SDavid du Colombier starterror(); 984*8ccd4a63SDavid du Colombier if(waserror()){ 985*8ccd4a63SDavid du Colombier _syserror(); 986*8ccd4a63SDavid du Colombier return -1; 987*8ccd4a63SDavid du Colombier } 988*8ccd4a63SDavid du Colombier n = _sysmount(fd, afd, new, flag, spec); 989*8ccd4a63SDavid du Colombier enderror(); 990*8ccd4a63SDavid du Colombier return n; 991*8ccd4a63SDavid du Colombier } 992*8ccd4a63SDavid du Colombier 993*8ccd4a63SDavid du Colombier int 994*8ccd4a63SDavid du Colombier sysunmount(char *old, char *new) 995*8ccd4a63SDavid du Colombier { 996*8ccd4a63SDavid du Colombier int n; 997*8ccd4a63SDavid du Colombier 998*8ccd4a63SDavid du Colombier starterror(); 999*8ccd4a63SDavid du Colombier if(waserror()){ 1000*8ccd4a63SDavid du Colombier _syserror(); 1001*8ccd4a63SDavid du Colombier return -1; 1002*8ccd4a63SDavid du Colombier } 1003*8ccd4a63SDavid du Colombier n = _sysunmount(old, new); 1004*8ccd4a63SDavid du Colombier enderror(); 1005*8ccd4a63SDavid du Colombier return n; 1006*8ccd4a63SDavid du Colombier } 1007*8ccd4a63SDavid du Colombier 1008*8ccd4a63SDavid du Colombier int 1009*8ccd4a63SDavid du Colombier sysopen(char *name, int mode) 1010*8ccd4a63SDavid du Colombier { 1011*8ccd4a63SDavid du Colombier int n; 1012*8ccd4a63SDavid du Colombier 1013*8ccd4a63SDavid du Colombier starterror(); 1014*8ccd4a63SDavid du Colombier if(waserror()){ 1015*8ccd4a63SDavid du Colombier _syserror(); 1016*8ccd4a63SDavid du Colombier return -1; 1017*8ccd4a63SDavid du Colombier } 1018*8ccd4a63SDavid du Colombier n = _sysopen(name, mode); 1019*8ccd4a63SDavid du Colombier enderror(); 1020*8ccd4a63SDavid du Colombier return n; 1021*8ccd4a63SDavid du Colombier } 1022*8ccd4a63SDavid du Colombier 1023*8ccd4a63SDavid du Colombier int 1024*8ccd4a63SDavid du Colombier syspipe(int *fd) 1025*8ccd4a63SDavid du Colombier { 1026*8ccd4a63SDavid du Colombier int n; 1027*8ccd4a63SDavid du Colombier 1028*8ccd4a63SDavid du Colombier starterror(); 1029*8ccd4a63SDavid du Colombier if(waserror()){ 1030*8ccd4a63SDavid du Colombier _syserror(); 1031*8ccd4a63SDavid du Colombier return -1; 1032*8ccd4a63SDavid du Colombier } 1033*8ccd4a63SDavid du Colombier n = _syspipe(fd); 1034*8ccd4a63SDavid du Colombier enderror(); 1035*8ccd4a63SDavid du Colombier return n; 1036*8ccd4a63SDavid du Colombier } 1037*8ccd4a63SDavid du Colombier 1038*8ccd4a63SDavid du Colombier long 1039*8ccd4a63SDavid du Colombier syspread(int fd, void *buf, long n, vlong off) 1040*8ccd4a63SDavid du Colombier { 1041*8ccd4a63SDavid du Colombier starterror(); 1042*8ccd4a63SDavid du Colombier if(waserror()){ 1043*8ccd4a63SDavid du Colombier _syserror(); 1044*8ccd4a63SDavid du Colombier return -1; 1045*8ccd4a63SDavid du Colombier } 1046*8ccd4a63SDavid du Colombier n = _syspread(fd, buf, n, off); 1047*8ccd4a63SDavid du Colombier enderror(); 1048*8ccd4a63SDavid du Colombier return n; 1049*8ccd4a63SDavid du Colombier } 1050*8ccd4a63SDavid du Colombier 1051*8ccd4a63SDavid du Colombier long 1052*8ccd4a63SDavid du Colombier syspwrite(int fd, void *buf, long n, vlong off) 1053*8ccd4a63SDavid du Colombier { 1054*8ccd4a63SDavid du Colombier starterror(); 1055*8ccd4a63SDavid du Colombier if(waserror()){ 1056*8ccd4a63SDavid du Colombier _syserror(); 1057*8ccd4a63SDavid du Colombier return -1; 1058*8ccd4a63SDavid du Colombier } 1059*8ccd4a63SDavid du Colombier n = _syspwrite(fd, buf, n, off); 1060*8ccd4a63SDavid du Colombier enderror(); 1061*8ccd4a63SDavid du Colombier return n; 1062*8ccd4a63SDavid du Colombier } 1063*8ccd4a63SDavid du Colombier 1064*8ccd4a63SDavid du Colombier long 1065*8ccd4a63SDavid du Colombier sysread(int fd, void *buf, long n) 1066*8ccd4a63SDavid du Colombier { 1067*8ccd4a63SDavid du Colombier starterror(); 1068*8ccd4a63SDavid du Colombier if(waserror()){ 1069*8ccd4a63SDavid du Colombier _syserror(); 1070*8ccd4a63SDavid du Colombier return -1; 1071*8ccd4a63SDavid du Colombier } 1072*8ccd4a63SDavid du Colombier n = _syspread(fd, buf, n, (uvlong) ~0); 1073*8ccd4a63SDavid du Colombier enderror(); 1074*8ccd4a63SDavid du Colombier return n; 1075*8ccd4a63SDavid du Colombier } 1076*8ccd4a63SDavid du Colombier 1077*8ccd4a63SDavid du Colombier int 1078*8ccd4a63SDavid du Colombier sysremove(char *path) 1079*8ccd4a63SDavid du Colombier { 1080*8ccd4a63SDavid du Colombier int n; 1081*8ccd4a63SDavid du Colombier 1082*8ccd4a63SDavid du Colombier starterror(); 1083*8ccd4a63SDavid du Colombier if(waserror()){ 1084*8ccd4a63SDavid du Colombier _syserror(); 1085*8ccd4a63SDavid du Colombier return -1; 1086*8ccd4a63SDavid du Colombier } 1087*8ccd4a63SDavid du Colombier n = _sysremove(path); 1088*8ccd4a63SDavid du Colombier enderror(); 1089*8ccd4a63SDavid du Colombier return n; 1090*8ccd4a63SDavid du Colombier } 1091*8ccd4a63SDavid du Colombier 1092*8ccd4a63SDavid du Colombier vlong 1093*8ccd4a63SDavid du Colombier sysseek(int fd, vlong off, int whence) 1094*8ccd4a63SDavid du Colombier { 1095*8ccd4a63SDavid du Colombier starterror(); 1096*8ccd4a63SDavid du Colombier if(waserror()){ 1097*8ccd4a63SDavid du Colombier _syserror(); 1098*8ccd4a63SDavid du Colombier return -1; 1099*8ccd4a63SDavid du Colombier } 1100*8ccd4a63SDavid du Colombier off = _sysseek(fd, off, whence); 1101*8ccd4a63SDavid du Colombier enderror(); 1102*8ccd4a63SDavid du Colombier return off; 1103*8ccd4a63SDavid du Colombier } 1104*8ccd4a63SDavid du Colombier 1105*8ccd4a63SDavid du Colombier int 1106*8ccd4a63SDavid du Colombier sysstat(char *name, uchar *buf, int n) 1107*8ccd4a63SDavid du Colombier { 1108*8ccd4a63SDavid du Colombier starterror(); 1109*8ccd4a63SDavid du Colombier if(waserror()){ 1110*8ccd4a63SDavid du Colombier _syserror(); 1111*8ccd4a63SDavid du Colombier return -1; 1112*8ccd4a63SDavid du Colombier } 1113*8ccd4a63SDavid du Colombier n = _sysstat(name, buf, n); 1114*8ccd4a63SDavid du Colombier enderror(); 1115*8ccd4a63SDavid du Colombier return n; 1116*8ccd4a63SDavid du Colombier } 1117*8ccd4a63SDavid du Colombier 1118*8ccd4a63SDavid du Colombier long 1119*8ccd4a63SDavid du Colombier syswrite(int fd, void *buf, long n) 1120*8ccd4a63SDavid du Colombier { 1121*8ccd4a63SDavid du Colombier starterror(); 1122*8ccd4a63SDavid du Colombier if(waserror()){ 1123*8ccd4a63SDavid du Colombier _syserror(); 1124*8ccd4a63SDavid du Colombier return -1; 1125*8ccd4a63SDavid du Colombier } 1126*8ccd4a63SDavid du Colombier n = _syspwrite(fd, buf, n, (uvlong) ~0); 1127*8ccd4a63SDavid du Colombier enderror(); 1128*8ccd4a63SDavid du Colombier return n; 1129*8ccd4a63SDavid du Colombier } 1130*8ccd4a63SDavid du Colombier 1131*8ccd4a63SDavid du Colombier int 1132*8ccd4a63SDavid du Colombier syswstat(char *name, uchar *buf, int n) 1133*8ccd4a63SDavid du Colombier { 1134*8ccd4a63SDavid du Colombier starterror(); 1135*8ccd4a63SDavid du Colombier if(waserror()){ 1136*8ccd4a63SDavid du Colombier _syserror(); 1137*8ccd4a63SDavid du Colombier return -1; 1138*8ccd4a63SDavid du Colombier } 1139*8ccd4a63SDavid du Colombier n = _syswstat(name, buf, n); 1140*8ccd4a63SDavid du Colombier enderror(); 1141*8ccd4a63SDavid du Colombier return n; 1142*8ccd4a63SDavid du Colombier } 1143*8ccd4a63SDavid du Colombier 1144*8ccd4a63SDavid du Colombier void 1145*8ccd4a63SDavid du Colombier werrstr(char *f, ...) 1146*8ccd4a63SDavid du Colombier { 1147*8ccd4a63SDavid du Colombier char buf[ERRMAX]; 1148*8ccd4a63SDavid du Colombier va_list arg; 1149*8ccd4a63SDavid du Colombier 1150*8ccd4a63SDavid du Colombier va_start(arg, f); 1151*8ccd4a63SDavid du Colombier vsnprint(buf, sizeof buf, f, arg); 1152*8ccd4a63SDavid du Colombier va_end(arg); 1153*8ccd4a63SDavid du Colombier 1154*8ccd4a63SDavid du Colombier if(up->nerrlab) 1155*8ccd4a63SDavid du Colombier strecpy(up->errstr, up->errstr+ERRMAX, buf); 1156*8ccd4a63SDavid du Colombier else 1157*8ccd4a63SDavid du Colombier strecpy(up->syserrstr, up->syserrstr+ERRMAX, buf); 1158*8ccd4a63SDavid du Colombier } 1159*8ccd4a63SDavid du Colombier 1160*8ccd4a63SDavid du Colombier int 1161*8ccd4a63SDavid du Colombier errfmt(Fmt *fmt) 1162*8ccd4a63SDavid du Colombier { 1163*8ccd4a63SDavid du Colombier if(up->nerrlab) 1164*8ccd4a63SDavid du Colombier return fmtstrcpy(fmt, up->errstr); 1165*8ccd4a63SDavid du Colombier else 1166*8ccd4a63SDavid du Colombier return fmtstrcpy(fmt, up->syserrstr); 1167*8ccd4a63SDavid du Colombier } 1168*8ccd4a63SDavid du Colombier 1169*8ccd4a63SDavid du Colombier int 1170*8ccd4a63SDavid du Colombier errstr(char *buf, uint n) 1171*8ccd4a63SDavid du Colombier { 1172*8ccd4a63SDavid du Colombier char tmp[ERRMAX]; 1173*8ccd4a63SDavid du Colombier char *p; 1174*8ccd4a63SDavid du Colombier 1175*8ccd4a63SDavid du Colombier p = up->nerrlab ? up->errstr : up->syserrstr; 1176*8ccd4a63SDavid du Colombier memmove(tmp, p, ERRMAX); 1177*8ccd4a63SDavid du Colombier utfecpy(p, p+ERRMAX, buf); 1178*8ccd4a63SDavid du Colombier utfecpy(buf, buf+n, tmp); 1179*8ccd4a63SDavid du Colombier return strlen(buf); 1180*8ccd4a63SDavid du Colombier } 1181*8ccd4a63SDavid du Colombier 1182*8ccd4a63SDavid du Colombier int 1183*8ccd4a63SDavid du Colombier rerrstr(char *buf, uint n) 1184*8ccd4a63SDavid du Colombier { 1185*8ccd4a63SDavid du Colombier char *p; 1186*8ccd4a63SDavid du Colombier 1187*8ccd4a63SDavid du Colombier p = up->nerrlab ? up->errstr : up->syserrstr; 1188*8ccd4a63SDavid du Colombier utfecpy(buf, buf+n, p); 1189*8ccd4a63SDavid du Colombier return strlen(buf); 1190*8ccd4a63SDavid du Colombier } 1191*8ccd4a63SDavid du Colombier 1192*8ccd4a63SDavid du Colombier ulong 1193*8ccd4a63SDavid du Colombier _sysrendezvous(ulong arg0, ulong arg1) 1194*8ccd4a63SDavid du Colombier { 1195*8ccd4a63SDavid du Colombier ulong tag, val; 1196*8ccd4a63SDavid du Colombier Proc *p, **l; 1197*8ccd4a63SDavid du Colombier 1198*8ccd4a63SDavid du Colombier tag = arg0; 1199*8ccd4a63SDavid du Colombier l = &REND(up->rgrp, tag); 1200*8ccd4a63SDavid du Colombier up->rendval = ~0UL; 1201*8ccd4a63SDavid du Colombier 1202*8ccd4a63SDavid du Colombier lock(&up->rgrp->ref.lk); 1203*8ccd4a63SDavid du Colombier for(p = *l; p; p = p->rendhash) { 1204*8ccd4a63SDavid du Colombier if(p->rendtag == tag) { 1205*8ccd4a63SDavid du Colombier *l = p->rendhash; 1206*8ccd4a63SDavid du Colombier val = p->rendval; 1207*8ccd4a63SDavid du Colombier p->rendval = arg1; 1208*8ccd4a63SDavid du Colombier 1209*8ccd4a63SDavid du Colombier while(p->mach != 0) 1210*8ccd4a63SDavid du Colombier ; 1211*8ccd4a63SDavid du Colombier procwakeup(p); 1212*8ccd4a63SDavid du Colombier unlock(&up->rgrp->ref.lk); 1213*8ccd4a63SDavid du Colombier return val; 1214*8ccd4a63SDavid du Colombier } 1215*8ccd4a63SDavid du Colombier l = &p->rendhash; 1216*8ccd4a63SDavid du Colombier } 1217*8ccd4a63SDavid du Colombier 1218*8ccd4a63SDavid du Colombier /* Going to sleep here */ 1219*8ccd4a63SDavid du Colombier up->rendtag = tag; 1220*8ccd4a63SDavid du Colombier up->rendval = arg1; 1221*8ccd4a63SDavid du Colombier up->rendhash = *l; 1222*8ccd4a63SDavid du Colombier *l = up; 1223*8ccd4a63SDavid du Colombier up->state = Rendezvous; 1224*8ccd4a63SDavid du Colombier unlock(&up->rgrp->ref.lk); 1225*8ccd4a63SDavid du Colombier 1226*8ccd4a63SDavid du Colombier procsleep(); 1227*8ccd4a63SDavid du Colombier 1228*8ccd4a63SDavid du Colombier return up->rendval; 1229*8ccd4a63SDavid du Colombier } 1230*8ccd4a63SDavid du Colombier 1231*8ccd4a63SDavid du Colombier ulong 1232*8ccd4a63SDavid du Colombier sysrendezvous(ulong tag, ulong val) 1233*8ccd4a63SDavid du Colombier { 1234*8ccd4a63SDavid du Colombier ulong n; 1235*8ccd4a63SDavid du Colombier 1236*8ccd4a63SDavid du Colombier starterror(); 1237*8ccd4a63SDavid du Colombier if(waserror()){ 1238*8ccd4a63SDavid du Colombier _syserror(); 1239*8ccd4a63SDavid du Colombier return -1; 1240*8ccd4a63SDavid du Colombier } 1241*8ccd4a63SDavid du Colombier n = _sysrendezvous(tag, val); 1242*8ccd4a63SDavid du Colombier enderror(); 1243*8ccd4a63SDavid du Colombier return n; 1244*8ccd4a63SDavid du Colombier } 1245