18ccd4a63SDavid du Colombier #include "u.h" 28ccd4a63SDavid du Colombier #include "lib.h" 38ccd4a63SDavid du Colombier #include "dat.h" 48ccd4a63SDavid du Colombier #include "fns.h" 58ccd4a63SDavid du Colombier #include "error.h" 68ccd4a63SDavid du Colombier 78ccd4a63SDavid du Colombier #include "user.h" 88ccd4a63SDavid du Colombier #undef open 98ccd4a63SDavid du Colombier #undef mount 108ccd4a63SDavid du Colombier #undef read 118ccd4a63SDavid du Colombier #undef write 128ccd4a63SDavid du Colombier #undef seek 138ccd4a63SDavid du Colombier #undef stat 148ccd4a63SDavid du Colombier #undef wstat 158ccd4a63SDavid du Colombier #undef remove 168ccd4a63SDavid du Colombier #undef close 178ccd4a63SDavid du Colombier #undef fstat 188ccd4a63SDavid du Colombier #undef fwstat 198ccd4a63SDavid du Colombier 208ccd4a63SDavid du Colombier /* 218ccd4a63SDavid du Colombier * The sys*() routines needn't poperror() as they return directly to syscall(). 228ccd4a63SDavid du Colombier */ 238ccd4a63SDavid du Colombier 248ccd4a63SDavid du Colombier static void 258ccd4a63SDavid du Colombier unlockfgrp(Fgrp *f) 268ccd4a63SDavid du Colombier { 278ccd4a63SDavid du Colombier int ex; 288ccd4a63SDavid du Colombier 298ccd4a63SDavid du Colombier ex = f->exceed; 308ccd4a63SDavid du Colombier f->exceed = 0; 318ccd4a63SDavid du Colombier unlock(&f->ref.lk); 328ccd4a63SDavid du Colombier if(ex) 338ccd4a63SDavid du Colombier pprint("warning: process exceeds %d file descriptors\n", ex); 348ccd4a63SDavid du Colombier } 358ccd4a63SDavid du Colombier 368ccd4a63SDavid du Colombier int 378ccd4a63SDavid du Colombier growfd(Fgrp *f, int fd) /* fd is always >= 0 */ 388ccd4a63SDavid du Colombier { 398ccd4a63SDavid du Colombier Chan **newfd, **oldfd; 408ccd4a63SDavid du Colombier 418ccd4a63SDavid du Colombier if(fd < f->nfd) 428ccd4a63SDavid du Colombier return 0; 438ccd4a63SDavid du Colombier if(fd >= f->nfd+DELTAFD) 448ccd4a63SDavid du Colombier return -1; /* out of range */ 458ccd4a63SDavid du Colombier /* 468ccd4a63SDavid du Colombier * Unbounded allocation is unwise; besides, there are only 16 bits 478ccd4a63SDavid du Colombier * of fid in 9P 488ccd4a63SDavid du Colombier */ 498ccd4a63SDavid du Colombier if(f->nfd >= 5000){ 508ccd4a63SDavid du Colombier Exhausted: 518ccd4a63SDavid du Colombier print("no free file descriptors\n"); 528ccd4a63SDavid du Colombier return -1; 538ccd4a63SDavid du Colombier } 548ccd4a63SDavid du Colombier newfd = malloc((f->nfd+DELTAFD)*sizeof(Chan*)); 558ccd4a63SDavid du Colombier if(newfd == 0) 568ccd4a63SDavid du Colombier goto Exhausted; 578ccd4a63SDavid du Colombier oldfd = f->fd; 588ccd4a63SDavid du Colombier memmove(newfd, oldfd, f->nfd*sizeof(Chan*)); 598ccd4a63SDavid du Colombier f->fd = newfd; 608ccd4a63SDavid du Colombier free(oldfd); 618ccd4a63SDavid du Colombier f->nfd += DELTAFD; 628ccd4a63SDavid du Colombier if(fd > f->maxfd){ 638ccd4a63SDavid du Colombier if(fd/100 > f->maxfd/100) 648ccd4a63SDavid du Colombier f->exceed = (fd/100)*100; 658ccd4a63SDavid du Colombier f->maxfd = fd; 668ccd4a63SDavid du Colombier } 678ccd4a63SDavid du Colombier return 1; 688ccd4a63SDavid du Colombier } 698ccd4a63SDavid du Colombier 708ccd4a63SDavid du Colombier /* 718ccd4a63SDavid du Colombier * this assumes that the fgrp is locked 728ccd4a63SDavid du Colombier */ 738ccd4a63SDavid du Colombier int 748ccd4a63SDavid du Colombier findfreefd(Fgrp *f, int start) 758ccd4a63SDavid du Colombier { 768ccd4a63SDavid du Colombier int fd; 778ccd4a63SDavid du Colombier 788ccd4a63SDavid du Colombier for(fd=start; fd<f->nfd; fd++) 798ccd4a63SDavid du Colombier if(f->fd[fd] == 0) 808ccd4a63SDavid du Colombier break; 818ccd4a63SDavid du Colombier if(fd >= f->nfd && growfd(f, fd) < 0) 828ccd4a63SDavid du Colombier return -1; 838ccd4a63SDavid du Colombier return fd; 848ccd4a63SDavid du Colombier } 858ccd4a63SDavid du Colombier 868ccd4a63SDavid du Colombier int 878ccd4a63SDavid du Colombier newfd(Chan *c) 888ccd4a63SDavid du Colombier { 898ccd4a63SDavid du Colombier int fd; 908ccd4a63SDavid du Colombier Fgrp *f; 918ccd4a63SDavid du Colombier 928ccd4a63SDavid du Colombier f = up->fgrp; 938ccd4a63SDavid du Colombier lock(&f->ref.lk); 948ccd4a63SDavid du Colombier fd = findfreefd(f, 0); 958ccd4a63SDavid du Colombier if(fd < 0){ 968ccd4a63SDavid du Colombier unlockfgrp(f); 978ccd4a63SDavid du Colombier return -1; 988ccd4a63SDavid du Colombier } 998ccd4a63SDavid du Colombier if(fd > f->maxfd) 1008ccd4a63SDavid du Colombier f->maxfd = fd; 1018ccd4a63SDavid du Colombier f->fd[fd] = c; 1028ccd4a63SDavid du Colombier unlockfgrp(f); 1038ccd4a63SDavid du Colombier return fd; 1048ccd4a63SDavid du Colombier } 1058ccd4a63SDavid du Colombier 1068ccd4a63SDavid du Colombier int 1078ccd4a63SDavid du Colombier newfd2(int fd[2], Chan *c[2]) 1088ccd4a63SDavid du Colombier { 1098ccd4a63SDavid du Colombier Fgrp *f; 1108ccd4a63SDavid du Colombier 1118ccd4a63SDavid du Colombier f = up->fgrp; 1128ccd4a63SDavid du Colombier lock(&f->ref.lk); 1138ccd4a63SDavid du Colombier fd[0] = findfreefd(f, 0); 1148ccd4a63SDavid du Colombier if(fd[0] < 0){ 1158ccd4a63SDavid du Colombier unlockfgrp(f); 1168ccd4a63SDavid du Colombier return -1; 1178ccd4a63SDavid du Colombier } 1188ccd4a63SDavid du Colombier fd[1] = findfreefd(f, fd[0]+1); 1198ccd4a63SDavid du Colombier if(fd[1] < 0){ 1208ccd4a63SDavid du Colombier unlockfgrp(f); 1218ccd4a63SDavid du Colombier return -1; 1228ccd4a63SDavid du Colombier } 1238ccd4a63SDavid du Colombier if(fd[1] > f->maxfd) 1248ccd4a63SDavid du Colombier f->maxfd = fd[1]; 1258ccd4a63SDavid du Colombier f->fd[fd[0]] = c[0]; 1268ccd4a63SDavid du Colombier f->fd[fd[1]] = c[1]; 1278ccd4a63SDavid du Colombier unlockfgrp(f); 1288ccd4a63SDavid du Colombier 1298ccd4a63SDavid du Colombier return 0; 1308ccd4a63SDavid du Colombier } 1318ccd4a63SDavid du Colombier 1328ccd4a63SDavid du Colombier Chan* 1338ccd4a63SDavid du Colombier fdtochan(int fd, int mode, int chkmnt, int iref) 1348ccd4a63SDavid du Colombier { 1358ccd4a63SDavid du Colombier Chan *c; 1368ccd4a63SDavid du Colombier Fgrp *f; 1378ccd4a63SDavid du Colombier 1388ccd4a63SDavid du Colombier c = 0; 1398ccd4a63SDavid du Colombier f = up->fgrp; 1408ccd4a63SDavid du Colombier 1418ccd4a63SDavid du Colombier lock(&f->ref.lk); 1428ccd4a63SDavid du Colombier if(fd<0 || f->nfd<=fd || (c = f->fd[fd])==0) { 1438ccd4a63SDavid du Colombier unlock(&f->ref.lk); 1448ccd4a63SDavid du Colombier error(Ebadfd); 1458ccd4a63SDavid du Colombier } 1468ccd4a63SDavid du Colombier if(iref) 1478ccd4a63SDavid du Colombier incref(&c->ref); 1488ccd4a63SDavid du Colombier unlock(&f->ref.lk); 1498ccd4a63SDavid du Colombier 1508ccd4a63SDavid du Colombier if(chkmnt && (c->flag&CMSG)) { 1518ccd4a63SDavid du Colombier if(iref) 1528ccd4a63SDavid du Colombier cclose(c); 1538ccd4a63SDavid du Colombier error(Ebadusefd); 1548ccd4a63SDavid du Colombier } 1558ccd4a63SDavid du Colombier 1568ccd4a63SDavid du Colombier if(mode<0 || c->mode==ORDWR) 1578ccd4a63SDavid du Colombier return c; 1588ccd4a63SDavid du Colombier 1598ccd4a63SDavid du Colombier if((mode&OTRUNC) && c->mode==OREAD) { 1608ccd4a63SDavid du Colombier if(iref) 1618ccd4a63SDavid du Colombier cclose(c); 1628ccd4a63SDavid du Colombier error(Ebadusefd); 1638ccd4a63SDavid du Colombier } 1648ccd4a63SDavid du Colombier 1658ccd4a63SDavid du Colombier if((mode&~OTRUNC) != c->mode) { 1668ccd4a63SDavid du Colombier if(iref) 1678ccd4a63SDavid du Colombier cclose(c); 1688ccd4a63SDavid du Colombier error(Ebadusefd); 1698ccd4a63SDavid du Colombier } 1708ccd4a63SDavid du Colombier 1718ccd4a63SDavid du Colombier return c; 1728ccd4a63SDavid du Colombier } 1738ccd4a63SDavid du Colombier 1748ccd4a63SDavid du Colombier int 1758ccd4a63SDavid du Colombier openmode(ulong o) 1768ccd4a63SDavid du Colombier { 1778ccd4a63SDavid du Colombier o &= ~(OTRUNC|OCEXEC|ORCLOSE); 1788ccd4a63SDavid du Colombier if(o > OEXEC) 1798ccd4a63SDavid du Colombier error(Ebadarg); 1808ccd4a63SDavid du Colombier if(o == OEXEC) 1818ccd4a63SDavid du Colombier return OREAD; 1828ccd4a63SDavid du Colombier return o; 1838ccd4a63SDavid du Colombier } 1848ccd4a63SDavid du Colombier 1858ccd4a63SDavid du Colombier long 1868ccd4a63SDavid du Colombier _sysfd2path(int fd, char *buf, uint nbuf) 1878ccd4a63SDavid du Colombier { 1888ccd4a63SDavid du Colombier Chan *c; 1898ccd4a63SDavid du Colombier 1908ccd4a63SDavid du Colombier c = fdtochan(fd, -1, 0, 1); 1918ccd4a63SDavid du Colombier 1928ccd4a63SDavid du Colombier if(c->name == nil) 1938ccd4a63SDavid du Colombier snprint(buf, nbuf, "<null>"); 1948ccd4a63SDavid du Colombier else 1958ccd4a63SDavid du Colombier snprint(buf, nbuf, "%s", c->name->s); 1968ccd4a63SDavid du Colombier cclose(c); 1978ccd4a63SDavid du Colombier return 0; 1988ccd4a63SDavid du Colombier } 1998ccd4a63SDavid du Colombier 2008ccd4a63SDavid du Colombier long 2018ccd4a63SDavid du Colombier _syspipe(int fd[2]) 2028ccd4a63SDavid du Colombier { 2038ccd4a63SDavid du Colombier Chan *c[2]; 2048ccd4a63SDavid du Colombier Dev *d; 2058ccd4a63SDavid du Colombier static char *datastr[] = {"data", "data1"}; 2068ccd4a63SDavid du Colombier 2078ccd4a63SDavid du Colombier d = devtab[devno('|', 0)]; 2088ccd4a63SDavid du Colombier c[0] = namec("#|", Atodir, 0, 0); 2098ccd4a63SDavid du Colombier c[1] = 0; 2108ccd4a63SDavid du Colombier fd[0] = -1; 2118ccd4a63SDavid du Colombier fd[1] = -1; 2128ccd4a63SDavid du Colombier 2138ccd4a63SDavid du Colombier if(waserror()){ 2148ccd4a63SDavid du Colombier cclose(c[0]); 2158ccd4a63SDavid du Colombier if(c[1]) 2168ccd4a63SDavid du Colombier cclose(c[1]); 2178ccd4a63SDavid du Colombier nexterror(); 2188ccd4a63SDavid du Colombier } 2198ccd4a63SDavid du Colombier c[1] = cclone(c[0]); 2208ccd4a63SDavid du Colombier if(walk(&c[0], datastr+0, 1, 1, nil) < 0) 2218ccd4a63SDavid du Colombier error(Egreg); 2228ccd4a63SDavid du Colombier if(walk(&c[1], datastr+1, 1, 1, nil) < 0) 2238ccd4a63SDavid du Colombier error(Egreg); 2248ccd4a63SDavid du Colombier c[0] = d->open(c[0], ORDWR); 2258ccd4a63SDavid du Colombier c[1] = d->open(c[1], ORDWR); 2268ccd4a63SDavid du Colombier if(newfd2(fd, c) < 0) 2278ccd4a63SDavid du Colombier error(Enofd); 2288ccd4a63SDavid du Colombier poperror(); 2298ccd4a63SDavid du Colombier 2308ccd4a63SDavid du Colombier return 0; 2318ccd4a63SDavid du Colombier } 2328ccd4a63SDavid du Colombier 2338ccd4a63SDavid du Colombier long 2348ccd4a63SDavid du Colombier _sysdup(int fd0, int fd1) 2358ccd4a63SDavid du Colombier { 2368ccd4a63SDavid du Colombier int fd; 2378ccd4a63SDavid du Colombier Chan *c, *oc; 2388ccd4a63SDavid du Colombier Fgrp *f = up->fgrp; 2398ccd4a63SDavid du Colombier 2408ccd4a63SDavid du Colombier /* 2418ccd4a63SDavid du Colombier * Close after dup'ing, so date > #d/1 works 2428ccd4a63SDavid du Colombier */ 2438ccd4a63SDavid du Colombier c = fdtochan(fd0, -1, 0, 1); 2448ccd4a63SDavid du Colombier fd = fd1; 2458ccd4a63SDavid du Colombier if(fd != -1){ 2468ccd4a63SDavid du Colombier lock(&f->ref.lk); 2478ccd4a63SDavid du Colombier if(fd<0 || growfd(f, fd)<0) { 2488ccd4a63SDavid du Colombier unlockfgrp(f); 2498ccd4a63SDavid du Colombier cclose(c); 2508ccd4a63SDavid du Colombier error(Ebadfd); 2518ccd4a63SDavid du Colombier } 2528ccd4a63SDavid du Colombier if(fd > f->maxfd) 2538ccd4a63SDavid du Colombier f->maxfd = fd; 2548ccd4a63SDavid du Colombier 2558ccd4a63SDavid du Colombier oc = f->fd[fd]; 2568ccd4a63SDavid du Colombier f->fd[fd] = c; 2578ccd4a63SDavid du Colombier unlockfgrp(f); 2588ccd4a63SDavid du Colombier if(oc) 2598ccd4a63SDavid du Colombier cclose(oc); 2608ccd4a63SDavid du Colombier }else{ 2618ccd4a63SDavid du Colombier if(waserror()) { 2628ccd4a63SDavid du Colombier cclose(c); 2638ccd4a63SDavid du Colombier nexterror(); 2648ccd4a63SDavid du Colombier } 2658ccd4a63SDavid du Colombier fd = newfd(c); 2668ccd4a63SDavid du Colombier if(fd < 0) 2678ccd4a63SDavid du Colombier error(Enofd); 2688ccd4a63SDavid du Colombier poperror(); 2698ccd4a63SDavid du Colombier } 2708ccd4a63SDavid du Colombier 2718ccd4a63SDavid du Colombier return fd; 2728ccd4a63SDavid du Colombier } 2738ccd4a63SDavid du Colombier 2748ccd4a63SDavid du Colombier long 2758ccd4a63SDavid du Colombier _sysopen(char *name, int mode) 2768ccd4a63SDavid du Colombier { 2778ccd4a63SDavid du Colombier int fd; 2788ccd4a63SDavid du Colombier Chan *c = 0; 2798ccd4a63SDavid du Colombier 2808ccd4a63SDavid du Colombier openmode(mode); /* error check only */ 2818ccd4a63SDavid du Colombier if(waserror()){ 2828ccd4a63SDavid du Colombier if(c) 2838ccd4a63SDavid du Colombier cclose(c); 2848ccd4a63SDavid du Colombier nexterror(); 2858ccd4a63SDavid du Colombier } 2868ccd4a63SDavid du Colombier c = namec(name, Aopen, mode, 0); 2878ccd4a63SDavid du Colombier fd = newfd(c); 2888ccd4a63SDavid du Colombier if(fd < 0) 2898ccd4a63SDavid du Colombier error(Enofd); 2908ccd4a63SDavid du Colombier poperror(); 2918ccd4a63SDavid du Colombier return fd; 2928ccd4a63SDavid du Colombier } 2938ccd4a63SDavid du Colombier 2948ccd4a63SDavid du Colombier void 2958ccd4a63SDavid du Colombier fdclose(int fd, int flag) 2968ccd4a63SDavid du Colombier { 2978ccd4a63SDavid du Colombier int i; 2988ccd4a63SDavid du Colombier Chan *c; 2998ccd4a63SDavid du Colombier Fgrp *f = up->fgrp; 3008ccd4a63SDavid du Colombier 3018ccd4a63SDavid du Colombier lock(&f->ref.lk); 3028ccd4a63SDavid du Colombier c = f->fd[fd]; 3038ccd4a63SDavid du Colombier if(c == 0){ 3048ccd4a63SDavid du Colombier /* can happen for users with shared fd tables */ 3058ccd4a63SDavid du Colombier unlock(&f->ref.lk); 3068ccd4a63SDavid du Colombier return; 3078ccd4a63SDavid du Colombier } 3088ccd4a63SDavid du Colombier if(flag){ 3098ccd4a63SDavid du Colombier if(c==0 || !(c->flag&flag)){ 3108ccd4a63SDavid du Colombier unlock(&f->ref.lk); 3118ccd4a63SDavid du Colombier return; 3128ccd4a63SDavid du Colombier } 3138ccd4a63SDavid du Colombier } 3148ccd4a63SDavid du Colombier f->fd[fd] = 0; 3158ccd4a63SDavid du Colombier if(fd == f->maxfd) 3168ccd4a63SDavid du Colombier for(i=fd; --i>=0 && f->fd[i]==0; ) 3178ccd4a63SDavid du Colombier f->maxfd = i; 3188ccd4a63SDavid du Colombier 3198ccd4a63SDavid du Colombier unlock(&f->ref.lk); 3208ccd4a63SDavid du Colombier cclose(c); 3218ccd4a63SDavid du Colombier } 3228ccd4a63SDavid du Colombier 3238ccd4a63SDavid du Colombier long 3248ccd4a63SDavid du Colombier _sysclose(int fd) 3258ccd4a63SDavid du Colombier { 3268ccd4a63SDavid du Colombier fdtochan(fd, -1, 0, 0); 3278ccd4a63SDavid du Colombier fdclose(fd, 0); 3288ccd4a63SDavid du Colombier 3298ccd4a63SDavid du Colombier return 0; 3308ccd4a63SDavid du Colombier } 3318ccd4a63SDavid du Colombier 3328ccd4a63SDavid du Colombier long 3338ccd4a63SDavid du Colombier unionread(Chan *c, void *va, long n) 3348ccd4a63SDavid du Colombier { 3358ccd4a63SDavid du Colombier int i; 3368ccd4a63SDavid du Colombier long nr; 3378ccd4a63SDavid du Colombier Mhead *m; 3388ccd4a63SDavid du Colombier Mount *mount; 3398ccd4a63SDavid du Colombier 3408ccd4a63SDavid du Colombier qlock(&c->umqlock); 3418ccd4a63SDavid du Colombier m = c->umh; 3428ccd4a63SDavid du Colombier rlock(&m->lock); 3438ccd4a63SDavid du Colombier mount = m->mount; 3448ccd4a63SDavid du Colombier /* bring mount in sync with c->uri and c->umc */ 3458ccd4a63SDavid du Colombier for(i = 0; mount != nil && i < c->uri; i++) 3468ccd4a63SDavid du Colombier mount = mount->next; 3478ccd4a63SDavid du Colombier 3488ccd4a63SDavid du Colombier nr = 0; 3498ccd4a63SDavid du Colombier while(mount != nil) { 3508ccd4a63SDavid du Colombier /* Error causes component of union to be skipped */ 3518ccd4a63SDavid du Colombier if(mount->to && !waserror()) { 3528ccd4a63SDavid du Colombier if(c->umc == nil){ 3538ccd4a63SDavid du Colombier c->umc = cclone(mount->to); 3548ccd4a63SDavid du Colombier c->umc = devtab[c->umc->type]->open(c->umc, OREAD); 3558ccd4a63SDavid du Colombier } 3568ccd4a63SDavid du Colombier 3578ccd4a63SDavid du Colombier nr = devtab[c->umc->type]->read(c->umc, va, n, c->umc->offset); 3588ccd4a63SDavid du Colombier c->umc->offset += nr; 3598ccd4a63SDavid du Colombier poperror(); 3608ccd4a63SDavid du Colombier } 3618ccd4a63SDavid du Colombier if(nr > 0) 3628ccd4a63SDavid du Colombier break; 3638ccd4a63SDavid du Colombier 3648ccd4a63SDavid du Colombier /* Advance to next element */ 3658ccd4a63SDavid du Colombier c->uri++; 3668ccd4a63SDavid du Colombier if(c->umc) { 3678ccd4a63SDavid du Colombier cclose(c->umc); 3688ccd4a63SDavid du Colombier c->umc = nil; 3698ccd4a63SDavid du Colombier } 3708ccd4a63SDavid du Colombier mount = mount->next; 3718ccd4a63SDavid du Colombier } 3728ccd4a63SDavid du Colombier runlock(&m->lock); 3738ccd4a63SDavid du Colombier qunlock(&c->umqlock); 3748ccd4a63SDavid du Colombier return nr; 3758ccd4a63SDavid du Colombier } 3768ccd4a63SDavid du Colombier 3778ccd4a63SDavid du Colombier static long 3788ccd4a63SDavid du Colombier kread(int fd, void *buf, long n, vlong *offp) 3798ccd4a63SDavid du Colombier { 3808ccd4a63SDavid du Colombier int dir; 3818ccd4a63SDavid du Colombier Chan *c; 3828ccd4a63SDavid du Colombier vlong off; 3838ccd4a63SDavid du Colombier 3848ccd4a63SDavid du Colombier c = fdtochan(fd, OREAD, 1, 1); 3858ccd4a63SDavid du Colombier 3868ccd4a63SDavid du Colombier if(waserror()) { 3878ccd4a63SDavid du Colombier cclose(c); 3888ccd4a63SDavid du Colombier nexterror(); 3898ccd4a63SDavid du Colombier } 3908ccd4a63SDavid du Colombier 3918ccd4a63SDavid du Colombier dir = c->qid.type&QTDIR; 3928ccd4a63SDavid du Colombier /* 3938ccd4a63SDavid du Colombier * The offset is passed through on directories, normally. sysseek complains but 3948ccd4a63SDavid du Colombier * pread is used by servers and e.g. exportfs that shouldn't need to worry about this issue. 3958ccd4a63SDavid du Colombier */ 3968ccd4a63SDavid du Colombier 3978ccd4a63SDavid du Colombier if(offp == nil) /* use and maintain channel's offset */ 3988ccd4a63SDavid du Colombier off = c->offset; 3998ccd4a63SDavid du Colombier else 4008ccd4a63SDavid du Colombier off = *offp; 4018ccd4a63SDavid du Colombier 4028ccd4a63SDavid du Colombier if(off < 0) 4038ccd4a63SDavid du Colombier error(Enegoff); 4048ccd4a63SDavid du Colombier 4058ccd4a63SDavid du Colombier if(dir && c->umh) 4068ccd4a63SDavid du Colombier n = unionread(c, buf, n); 4078ccd4a63SDavid du Colombier else 4088ccd4a63SDavid du Colombier n = devtab[c->type]->read(c, buf, n, off); 4098ccd4a63SDavid du Colombier 4108ccd4a63SDavid du Colombier if(offp == nil){ 4118ccd4a63SDavid du Colombier lock(&c->ref.lk); 4128ccd4a63SDavid du Colombier c->offset += n; 4138ccd4a63SDavid du Colombier unlock(&c->ref.lk); 4148ccd4a63SDavid du Colombier } 4158ccd4a63SDavid du Colombier 4168ccd4a63SDavid du Colombier poperror(); 4178ccd4a63SDavid du Colombier cclose(c); 4188ccd4a63SDavid du Colombier 4198ccd4a63SDavid du Colombier return n; 4208ccd4a63SDavid du Colombier } 4218ccd4a63SDavid du Colombier 4228ccd4a63SDavid du Colombier /* name conflicts with netbsd 4238ccd4a63SDavid du Colombier long 4248ccd4a63SDavid du Colombier _sys_read(int fd, void *buf, long n) 4258ccd4a63SDavid du Colombier { 4268ccd4a63SDavid du Colombier return kread(fd, buf, n, nil); 4278ccd4a63SDavid du Colombier } 4288ccd4a63SDavid du Colombier */ 4298ccd4a63SDavid du Colombier 4308ccd4a63SDavid du Colombier long 4318ccd4a63SDavid du Colombier _syspread(int fd, void *buf, long n, vlong off) 4328ccd4a63SDavid du Colombier { 4338ccd4a63SDavid du Colombier if(off == ((uvlong) ~0)) 4348ccd4a63SDavid du Colombier return kread(fd, buf, n, nil); 4358ccd4a63SDavid du Colombier return kread(fd, buf, n, &off); 4368ccd4a63SDavid du Colombier } 4378ccd4a63SDavid du Colombier 4388ccd4a63SDavid du Colombier static long 4398ccd4a63SDavid du Colombier kwrite(int fd, void *buf, long nn, vlong *offp) 4408ccd4a63SDavid du Colombier { 4418ccd4a63SDavid du Colombier Chan *c; 4428ccd4a63SDavid du Colombier long m, n; 4438ccd4a63SDavid du Colombier vlong off; 4448ccd4a63SDavid du Colombier 4458ccd4a63SDavid du Colombier n = 0; 4468ccd4a63SDavid du Colombier c = fdtochan(fd, OWRITE, 1, 1); 4478ccd4a63SDavid du Colombier if(waserror()) { 4488ccd4a63SDavid du Colombier if(offp == nil){ 4498ccd4a63SDavid du Colombier lock(&c->ref.lk); 4508ccd4a63SDavid du Colombier c->offset -= n; 4518ccd4a63SDavid du Colombier unlock(&c->ref.lk); 4528ccd4a63SDavid du Colombier } 4538ccd4a63SDavid du Colombier cclose(c); 4548ccd4a63SDavid du Colombier nexterror(); 4558ccd4a63SDavid du Colombier } 4568ccd4a63SDavid du Colombier 4578ccd4a63SDavid du Colombier if(c->qid.type & QTDIR) 4588ccd4a63SDavid du Colombier error(Eisdir); 4598ccd4a63SDavid du Colombier 4608ccd4a63SDavid du Colombier n = nn; 4618ccd4a63SDavid du Colombier 4628ccd4a63SDavid du Colombier if(offp == nil){ /* use and maintain channel's offset */ 4638ccd4a63SDavid du Colombier lock(&c->ref.lk); 4648ccd4a63SDavid du Colombier off = c->offset; 4658ccd4a63SDavid du Colombier c->offset += n; 4668ccd4a63SDavid du Colombier unlock(&c->ref.lk); 4678ccd4a63SDavid du Colombier }else 4688ccd4a63SDavid du Colombier off = *offp; 4698ccd4a63SDavid du Colombier 4708ccd4a63SDavid du Colombier if(off < 0) 4718ccd4a63SDavid du Colombier error(Enegoff); 4728ccd4a63SDavid du Colombier 4738ccd4a63SDavid du Colombier m = devtab[c->type]->write(c, buf, n, off); 4748ccd4a63SDavid du Colombier 4758ccd4a63SDavid du Colombier if(offp == nil && m < n){ 4768ccd4a63SDavid du Colombier lock(&c->ref.lk); 4778ccd4a63SDavid du Colombier c->offset -= n - m; 4788ccd4a63SDavid du Colombier unlock(&c->ref.lk); 4798ccd4a63SDavid du Colombier } 4808ccd4a63SDavid du Colombier 4818ccd4a63SDavid du Colombier poperror(); 4828ccd4a63SDavid du Colombier cclose(c); 4838ccd4a63SDavid du Colombier 4848ccd4a63SDavid du Colombier return m; 4858ccd4a63SDavid du Colombier } 4868ccd4a63SDavid du Colombier 4878ccd4a63SDavid du Colombier long 4888ccd4a63SDavid du Colombier sys_write(int fd, void *buf, long n) 4898ccd4a63SDavid du Colombier { 4908ccd4a63SDavid du Colombier return kwrite(fd, buf, n, nil); 4918ccd4a63SDavid du Colombier } 4928ccd4a63SDavid du Colombier 4938ccd4a63SDavid du Colombier long 4948ccd4a63SDavid du Colombier _syspwrite(int fd, void *buf, long n, vlong off) 4958ccd4a63SDavid du Colombier { 4968ccd4a63SDavid du Colombier if(off == ((uvlong) ~0)) 4978ccd4a63SDavid du Colombier return kwrite(fd, buf, n, nil); 4988ccd4a63SDavid du Colombier return kwrite(fd, buf, n, &off); 4998ccd4a63SDavid du Colombier } 5008ccd4a63SDavid du Colombier 5018ccd4a63SDavid du Colombier static vlong 5028ccd4a63SDavid du Colombier _sysseek(int fd, vlong off, int whence) 5038ccd4a63SDavid du Colombier { 5048ccd4a63SDavid du Colombier Chan *c; 5058ccd4a63SDavid du Colombier uchar buf[sizeof(Dir)+100]; 5068ccd4a63SDavid du Colombier Dir dir; 5078ccd4a63SDavid du Colombier int n; 5088ccd4a63SDavid du Colombier 5098ccd4a63SDavid du Colombier c = fdtochan(fd, -1, 1, 1); 5108ccd4a63SDavid du Colombier if(waserror()){ 5118ccd4a63SDavid du Colombier cclose(c); 5128ccd4a63SDavid du Colombier nexterror(); 5138ccd4a63SDavid du Colombier } 5148ccd4a63SDavid du Colombier if(devtab[c->type]->dc == '|') 5158ccd4a63SDavid du Colombier error(Eisstream); 5168ccd4a63SDavid du Colombier 5178ccd4a63SDavid du Colombier switch(whence){ 5188ccd4a63SDavid du Colombier case 0: 5198ccd4a63SDavid du Colombier if((c->qid.type & QTDIR) && off != 0) 5208ccd4a63SDavid du Colombier error(Eisdir); 5218ccd4a63SDavid du Colombier if(off < 0) 5228ccd4a63SDavid du Colombier error(Enegoff); 5238ccd4a63SDavid du Colombier c->offset = off; 5248ccd4a63SDavid du Colombier break; 5258ccd4a63SDavid du Colombier 5268ccd4a63SDavid du Colombier case 1: 5278ccd4a63SDavid du Colombier if(c->qid.type & QTDIR) 5288ccd4a63SDavid du Colombier error(Eisdir); 5298ccd4a63SDavid du Colombier lock(&c->ref.lk); /* lock for read/write update */ 5308ccd4a63SDavid du Colombier off = off + c->offset; 5318ccd4a63SDavid du Colombier if(off < 0) 5328ccd4a63SDavid du Colombier error(Enegoff); 5338ccd4a63SDavid du Colombier c->offset = off; 5348ccd4a63SDavid du Colombier unlock(&c->ref.lk); 5358ccd4a63SDavid du Colombier break; 5368ccd4a63SDavid du Colombier 5378ccd4a63SDavid du Colombier case 2: 5388ccd4a63SDavid du Colombier if(c->qid.type & QTDIR) 5398ccd4a63SDavid du Colombier error(Eisdir); 5408ccd4a63SDavid du Colombier n = devtab[c->type]->stat(c, buf, sizeof buf); 5418ccd4a63SDavid du Colombier if(convM2D(buf, n, &dir, nil) == 0) 5428ccd4a63SDavid du Colombier error("internal error: stat error in seek"); 5438ccd4a63SDavid du Colombier off = dir.length + off; 5448ccd4a63SDavid du Colombier if(off < 0) 5458ccd4a63SDavid du Colombier error(Enegoff); 5468ccd4a63SDavid du Colombier c->offset = off; 5478ccd4a63SDavid du Colombier break; 5488ccd4a63SDavid du Colombier 5498ccd4a63SDavid du Colombier default: 5508ccd4a63SDavid du Colombier error(Ebadarg); 5518ccd4a63SDavid du Colombier } 5528ccd4a63SDavid du Colombier c->uri = 0; 5538ccd4a63SDavid du Colombier c->dri = 0; 5548ccd4a63SDavid du Colombier cclose(c); 5558ccd4a63SDavid du Colombier poperror(); 5568ccd4a63SDavid du Colombier return off; 5578ccd4a63SDavid du Colombier } 5588ccd4a63SDavid du Colombier 5598ccd4a63SDavid du Colombier void 5608ccd4a63SDavid du Colombier validstat(uchar *s, int n) 5618ccd4a63SDavid du Colombier { 5628ccd4a63SDavid du Colombier int m; 5638ccd4a63SDavid du Colombier char buf[64]; 5648ccd4a63SDavid du Colombier 5658ccd4a63SDavid du Colombier if(statcheck(s, n) < 0) 5668ccd4a63SDavid du Colombier error(Ebadstat); 5678ccd4a63SDavid du Colombier /* verify that name entry is acceptable */ 5688ccd4a63SDavid du Colombier s += STATFIXLEN - 4*BIT16SZ; /* location of first string */ 5698ccd4a63SDavid du Colombier /* 5708ccd4a63SDavid du Colombier * s now points at count for first string. 5718ccd4a63SDavid du Colombier * if it's too long, let the server decide; this is 5728ccd4a63SDavid du Colombier * only for his protection anyway. otherwise 5738ccd4a63SDavid du Colombier * we'd have to allocate and waserror. 5748ccd4a63SDavid du Colombier */ 5758ccd4a63SDavid du Colombier m = GBIT16(s); 5768ccd4a63SDavid du Colombier s += BIT16SZ; 5778ccd4a63SDavid du Colombier if(m+1 > sizeof buf) 5788ccd4a63SDavid du Colombier return; 5798ccd4a63SDavid du Colombier memmove(buf, s, m); 5808ccd4a63SDavid du Colombier buf[m] = '\0'; 5818ccd4a63SDavid du Colombier /* name could be '/' */ 5828ccd4a63SDavid du Colombier if(strcmp(buf, "/") != 0) 5838ccd4a63SDavid du Colombier validname(buf, 0); 5848ccd4a63SDavid du Colombier } 5858ccd4a63SDavid du Colombier 5868ccd4a63SDavid du Colombier long 5878ccd4a63SDavid du Colombier _sysfstat(int fd, void *buf, long n) 5888ccd4a63SDavid du Colombier { 5898ccd4a63SDavid du Colombier Chan *c; 5908ccd4a63SDavid du Colombier uint l; 5918ccd4a63SDavid du Colombier 5928ccd4a63SDavid du Colombier l = n; 5938ccd4a63SDavid du Colombier validaddr(buf, l, 1); 5948ccd4a63SDavid du Colombier c = fdtochan(fd, -1, 0, 1); 5958ccd4a63SDavid du Colombier if(waserror()) { 5968ccd4a63SDavid du Colombier cclose(c); 5978ccd4a63SDavid du Colombier nexterror(); 5988ccd4a63SDavid du Colombier } 5998ccd4a63SDavid du Colombier l = devtab[c->type]->stat(c, buf, l); 6008ccd4a63SDavid du Colombier poperror(); 6018ccd4a63SDavid du Colombier cclose(c); 6028ccd4a63SDavid du Colombier return l; 6038ccd4a63SDavid du Colombier } 6048ccd4a63SDavid du Colombier 6058ccd4a63SDavid du Colombier long 6068ccd4a63SDavid du Colombier _sysstat(char *name, void *buf, long n) 6078ccd4a63SDavid du Colombier { 6088ccd4a63SDavid du Colombier Chan *c; 6098ccd4a63SDavid du Colombier uint l; 6108ccd4a63SDavid du Colombier 6118ccd4a63SDavid du Colombier l = n; 6128ccd4a63SDavid du Colombier validaddr(buf, l, 1); 6138ccd4a63SDavid du Colombier validaddr(name, 1, 0); 6148ccd4a63SDavid du Colombier c = namec(name, Aaccess, 0, 0); 6158ccd4a63SDavid du Colombier if(waserror()){ 6168ccd4a63SDavid du Colombier cclose(c); 6178ccd4a63SDavid du Colombier nexterror(); 6188ccd4a63SDavid du Colombier } 6198ccd4a63SDavid du Colombier l = devtab[c->type]->stat(c, buf, l); 6208ccd4a63SDavid du Colombier poperror(); 6218ccd4a63SDavid du Colombier cclose(c); 6228ccd4a63SDavid du Colombier return l; 6238ccd4a63SDavid du Colombier } 6248ccd4a63SDavid du Colombier 6258ccd4a63SDavid du Colombier long 6268ccd4a63SDavid du Colombier _syschdir(char *name) 6278ccd4a63SDavid du Colombier { 6288ccd4a63SDavid du Colombier Chan *c; 6298ccd4a63SDavid du Colombier 6308ccd4a63SDavid du Colombier validaddr(name, 1, 0); 6318ccd4a63SDavid du Colombier 6328ccd4a63SDavid du Colombier c = namec(name, Atodir, 0, 0); 6338ccd4a63SDavid du Colombier cclose(up->dot); 6348ccd4a63SDavid du Colombier up->dot = c; 6358ccd4a63SDavid du Colombier return 0; 6368ccd4a63SDavid du Colombier } 6378ccd4a63SDavid du Colombier 6388ccd4a63SDavid du Colombier long 6398ccd4a63SDavid du Colombier bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec) 6408ccd4a63SDavid du Colombier { 6418ccd4a63SDavid du Colombier int ret; 6428ccd4a63SDavid du Colombier Chan *c0, *c1, *ac, *bc; 6438ccd4a63SDavid du Colombier struct{ 6448ccd4a63SDavid du Colombier Chan *chan; 6458ccd4a63SDavid du Colombier Chan *authchan; 6468ccd4a63SDavid du Colombier char *spec; 6478ccd4a63SDavid du Colombier int flags; 6488ccd4a63SDavid du Colombier }bogus; 6498ccd4a63SDavid du Colombier 6508ccd4a63SDavid du Colombier if((flag&~MMASK) || (flag&MORDER)==(MBEFORE|MAFTER)) 6518ccd4a63SDavid du Colombier error(Ebadarg); 6528ccd4a63SDavid du Colombier 6538ccd4a63SDavid du Colombier bogus.flags = flag & MCACHE; 6548ccd4a63SDavid du Colombier 6558ccd4a63SDavid du Colombier if(ismount){ 6568ccd4a63SDavid du Colombier if(up->pgrp->noattach) 6578ccd4a63SDavid du Colombier error(Enoattach); 6588ccd4a63SDavid du Colombier 6598ccd4a63SDavid du Colombier ac = nil; 6608ccd4a63SDavid du Colombier bc = fdtochan(fd, ORDWR, 0, 1); 6618ccd4a63SDavid du Colombier if(waserror()) { 6628ccd4a63SDavid du Colombier if(ac) 6638ccd4a63SDavid du Colombier cclose(ac); 6648ccd4a63SDavid du Colombier cclose(bc); 6658ccd4a63SDavid du Colombier nexterror(); 6668ccd4a63SDavid du Colombier } 6678ccd4a63SDavid du Colombier 6688ccd4a63SDavid du Colombier if(afd >= 0) 6698ccd4a63SDavid du Colombier ac = fdtochan(afd, ORDWR, 0, 1); 6708ccd4a63SDavid du Colombier 6718ccd4a63SDavid du Colombier bogus.chan = bc; 6728ccd4a63SDavid du Colombier bogus.authchan = ac; 6738ccd4a63SDavid du Colombier 6748ccd4a63SDavid du Colombier validaddr((ulong)spec, 1, 0); 6758ccd4a63SDavid du Colombier bogus.spec = spec; 6768ccd4a63SDavid du Colombier if(waserror()) 6778ccd4a63SDavid du Colombier error(Ebadspec); 6788ccd4a63SDavid du Colombier validname(spec, 1); 6798ccd4a63SDavid du Colombier poperror(); 6808ccd4a63SDavid du Colombier 6818ccd4a63SDavid du Colombier ret = devno('M', 0); 6828ccd4a63SDavid du Colombier c0 = devtab[ret]->attach((char*)&bogus); 6838ccd4a63SDavid du Colombier 6848ccd4a63SDavid du Colombier poperror(); 6858ccd4a63SDavid du Colombier if(ac) 6868ccd4a63SDavid du Colombier cclose(ac); 6878ccd4a63SDavid du Colombier cclose(bc); 6888ccd4a63SDavid du Colombier }else{ 6898ccd4a63SDavid du Colombier bogus.spec = 0; 6908ccd4a63SDavid du Colombier validaddr((ulong)arg0, 1, 0); 6918ccd4a63SDavid du Colombier c0 = namec(arg0, Abind, 0, 0); 6928ccd4a63SDavid du Colombier } 6938ccd4a63SDavid du Colombier 6948ccd4a63SDavid du Colombier if(waserror()){ 6958ccd4a63SDavid du Colombier cclose(c0); 6968ccd4a63SDavid du Colombier nexterror(); 6978ccd4a63SDavid du Colombier } 6988ccd4a63SDavid du Colombier 6998ccd4a63SDavid du Colombier validaddr((ulong)arg1, 1, 0); 7008ccd4a63SDavid du Colombier c1 = namec(arg1, Amount, 0, 0); 7018ccd4a63SDavid du Colombier if(waserror()){ 7028ccd4a63SDavid du Colombier cclose(c1); 7038ccd4a63SDavid du Colombier nexterror(); 7048ccd4a63SDavid du Colombier } 7058ccd4a63SDavid du Colombier 7068ccd4a63SDavid du Colombier ret = cmount(&c0, c1, flag, bogus.spec); 7078ccd4a63SDavid du Colombier 7088ccd4a63SDavid du Colombier poperror(); 7098ccd4a63SDavid du Colombier cclose(c1); 7108ccd4a63SDavid du Colombier poperror(); 7118ccd4a63SDavid du Colombier cclose(c0); 7128ccd4a63SDavid du Colombier if(ismount) 7138ccd4a63SDavid du Colombier fdclose(fd, 0); 7148ccd4a63SDavid du Colombier 7158ccd4a63SDavid du Colombier return ret; 7168ccd4a63SDavid du Colombier } 7178ccd4a63SDavid du Colombier 7188ccd4a63SDavid du Colombier long 7198ccd4a63SDavid du Colombier _sysbind(char *old, char *new, int flag) 7208ccd4a63SDavid du Colombier { 7218ccd4a63SDavid du Colombier return bindmount(0, -1, -1, old, new, flag, nil); 7228ccd4a63SDavid du Colombier } 7238ccd4a63SDavid du Colombier 7248ccd4a63SDavid du Colombier long 7258ccd4a63SDavid du Colombier _sysmount(int fd, int afd, char *new, int flag, char *spec) 7268ccd4a63SDavid du Colombier { 7278ccd4a63SDavid du Colombier return bindmount(1, fd, afd, nil, new, flag, spec); 7288ccd4a63SDavid du Colombier } 7298ccd4a63SDavid du Colombier 7308ccd4a63SDavid du Colombier long 7318ccd4a63SDavid du Colombier _sysunmount(char *old, char *new) 7328ccd4a63SDavid du Colombier { 7338ccd4a63SDavid du Colombier Chan *cmount, *cmounted; 7348ccd4a63SDavid du Colombier 7358ccd4a63SDavid du Colombier cmounted = 0; 7368ccd4a63SDavid du Colombier 7378ccd4a63SDavid du Colombier cmount = namec(new, Amount, 0, 0); 7388ccd4a63SDavid du Colombier 7398ccd4a63SDavid du Colombier if(old) { 7408ccd4a63SDavid du Colombier if(waserror()) { 7418ccd4a63SDavid du Colombier cclose(cmount); 7428ccd4a63SDavid du Colombier nexterror(); 7438ccd4a63SDavid du Colombier } 7448ccd4a63SDavid du Colombier validaddr(old, 1, 0); 7458ccd4a63SDavid du Colombier /* 7468ccd4a63SDavid du Colombier * This has to be namec(..., Aopen, ...) because 7478ccd4a63SDavid du Colombier * if arg[0] is something like /srv/cs or /fd/0, 7488ccd4a63SDavid du Colombier * opening it is the only way to get at the real 7498ccd4a63SDavid du Colombier * Chan underneath. 7508ccd4a63SDavid du Colombier */ 7518ccd4a63SDavid du Colombier cmounted = namec(old, Aopen, OREAD, 0); 7528ccd4a63SDavid du Colombier poperror(); 7538ccd4a63SDavid du Colombier } 7548ccd4a63SDavid du Colombier 7558ccd4a63SDavid du Colombier if(waserror()) { 7568ccd4a63SDavid du Colombier cclose(cmount); 7578ccd4a63SDavid du Colombier if(cmounted) 7588ccd4a63SDavid du Colombier cclose(cmounted); 7598ccd4a63SDavid du Colombier nexterror(); 7608ccd4a63SDavid du Colombier } 7618ccd4a63SDavid du Colombier 7628ccd4a63SDavid du Colombier cunmount(cmount, cmounted); 7638ccd4a63SDavid du Colombier cclose(cmount); 7648ccd4a63SDavid du Colombier if(cmounted) 7658ccd4a63SDavid du Colombier cclose(cmounted); 7668ccd4a63SDavid du Colombier poperror(); 7678ccd4a63SDavid du Colombier return 0; 7688ccd4a63SDavid du Colombier } 7698ccd4a63SDavid du Colombier 7708ccd4a63SDavid du Colombier long 7718ccd4a63SDavid du Colombier _syscreate(char *name, int mode, ulong perm) 7728ccd4a63SDavid du Colombier { 7738ccd4a63SDavid du Colombier int fd; 7748ccd4a63SDavid du Colombier Chan *c = 0; 7758ccd4a63SDavid du Colombier 7768ccd4a63SDavid du Colombier openmode(mode&~OEXCL); /* error check only; OEXCL okay here */ 7778ccd4a63SDavid du Colombier if(waserror()) { 7788ccd4a63SDavid du Colombier if(c) 7798ccd4a63SDavid du Colombier cclose(c); 7808ccd4a63SDavid du Colombier nexterror(); 7818ccd4a63SDavid du Colombier } 7828ccd4a63SDavid du Colombier validaddr(name, 1, 0); 7838ccd4a63SDavid du Colombier c = namec(name, Acreate, mode, perm); 7848ccd4a63SDavid du Colombier fd = newfd(c); 7858ccd4a63SDavid du Colombier if(fd < 0) 7868ccd4a63SDavid du Colombier error(Enofd); 7878ccd4a63SDavid du Colombier poperror(); 7888ccd4a63SDavid du Colombier return fd; 7898ccd4a63SDavid du Colombier } 7908ccd4a63SDavid du Colombier 7918ccd4a63SDavid du Colombier long 7928ccd4a63SDavid du Colombier _sysremove(char *name) 7938ccd4a63SDavid du Colombier { 7948ccd4a63SDavid du Colombier Chan *c; 7958ccd4a63SDavid du Colombier 7968ccd4a63SDavid du Colombier c = namec(name, Aremove, 0, 0); 7978ccd4a63SDavid du Colombier if(waserror()){ 7988ccd4a63SDavid du Colombier c->type = 0; /* see below */ 7998ccd4a63SDavid du Colombier cclose(c); 8008ccd4a63SDavid du Colombier nexterror(); 8018ccd4a63SDavid du Colombier } 8028ccd4a63SDavid du Colombier devtab[c->type]->remove(c); 8038ccd4a63SDavid du Colombier /* 8048ccd4a63SDavid du Colombier * Remove clunks the fid, but we need to recover the Chan 8058ccd4a63SDavid du Colombier * so fake it up. rootclose() is known to be a nop. 8068ccd4a63SDavid du Colombier */ 8078ccd4a63SDavid du Colombier c->type = 0; 8088ccd4a63SDavid du Colombier poperror(); 8098ccd4a63SDavid du Colombier cclose(c); 8108ccd4a63SDavid du Colombier return 0; 8118ccd4a63SDavid du Colombier } 8128ccd4a63SDavid du Colombier 8138ccd4a63SDavid du Colombier long 8148ccd4a63SDavid du Colombier _syswstat(char *name, void *buf, long n) 8158ccd4a63SDavid du Colombier { 8168ccd4a63SDavid du Colombier Chan *c; 8178ccd4a63SDavid du Colombier uint l; 8188ccd4a63SDavid du Colombier 8198ccd4a63SDavid du Colombier l = n; 8208ccd4a63SDavid du Colombier validstat(buf, l); 8218ccd4a63SDavid du Colombier validaddr(name, 1, 0); 8228ccd4a63SDavid du Colombier c = namec(name, Aaccess, 0, 0); 8238ccd4a63SDavid du Colombier if(waserror()){ 8248ccd4a63SDavid du Colombier cclose(c); 8258ccd4a63SDavid du Colombier nexterror(); 8268ccd4a63SDavid du Colombier } 8278ccd4a63SDavid du Colombier l = devtab[c->type]->wstat(c, buf, l); 8288ccd4a63SDavid du Colombier poperror(); 8298ccd4a63SDavid du Colombier cclose(c); 8308ccd4a63SDavid du Colombier return l; 8318ccd4a63SDavid du Colombier } 8328ccd4a63SDavid du Colombier 8338ccd4a63SDavid du Colombier long 8348ccd4a63SDavid du Colombier _sysfwstat(int fd, void *buf, long n) 8358ccd4a63SDavid du Colombier { 8368ccd4a63SDavid du Colombier Chan *c; 8378ccd4a63SDavid du Colombier uint l; 8388ccd4a63SDavid du Colombier 8398ccd4a63SDavid du Colombier l = n; 8408ccd4a63SDavid du Colombier validaddr(buf, l, 0); 8418ccd4a63SDavid du Colombier validstat(buf, l); 8428ccd4a63SDavid du Colombier c = fdtochan(fd, -1, 1, 1); 8438ccd4a63SDavid du Colombier if(waserror()) { 8448ccd4a63SDavid du Colombier cclose(c); 8458ccd4a63SDavid du Colombier nexterror(); 8468ccd4a63SDavid du Colombier } 8478ccd4a63SDavid du Colombier l = devtab[c->type]->wstat(c, buf, l); 8488ccd4a63SDavid du Colombier poperror(); 8498ccd4a63SDavid du Colombier cclose(c); 8508ccd4a63SDavid du Colombier return l; 8518ccd4a63SDavid du Colombier } 8528ccd4a63SDavid du Colombier 8538ccd4a63SDavid du Colombier 8548ccd4a63SDavid du Colombier static void 8558ccd4a63SDavid du Colombier starterror(void) 8568ccd4a63SDavid du Colombier { 8578ccd4a63SDavid du Colombier assert(up->nerrlab == 0); 8588ccd4a63SDavid du Colombier } 8598ccd4a63SDavid du Colombier 8608ccd4a63SDavid du Colombier static void 8618ccd4a63SDavid du Colombier _syserror(void) 8628ccd4a63SDavid du Colombier { 8638ccd4a63SDavid du Colombier char *p; 8648ccd4a63SDavid du Colombier 8658ccd4a63SDavid du Colombier p = up->syserrstr; 8668ccd4a63SDavid du Colombier up->syserrstr = up->errstr; 8678ccd4a63SDavid du Colombier up->errstr = p; 8688ccd4a63SDavid du Colombier } 8698ccd4a63SDavid du Colombier 8708ccd4a63SDavid du Colombier static void 8718ccd4a63SDavid du Colombier enderror(void) 8728ccd4a63SDavid du Colombier { 8738ccd4a63SDavid du Colombier assert(up->nerrlab == 1); 8748ccd4a63SDavid du Colombier poperror(); 8758ccd4a63SDavid du Colombier } 8768ccd4a63SDavid du Colombier 8778ccd4a63SDavid du Colombier int 8788ccd4a63SDavid du Colombier sysbind(char *old, char *new, int flag) 8798ccd4a63SDavid du Colombier { 8808ccd4a63SDavid du Colombier int n; 8818ccd4a63SDavid du Colombier 8828ccd4a63SDavid du Colombier starterror(); 8838ccd4a63SDavid du Colombier if(waserror()){ 8848ccd4a63SDavid du Colombier _syserror(); 8858ccd4a63SDavid du Colombier return -1; 8868ccd4a63SDavid du Colombier } 8878ccd4a63SDavid du Colombier n = _sysbind(old, new, flag); 8888ccd4a63SDavid du Colombier enderror(); 8898ccd4a63SDavid du Colombier return n; 8908ccd4a63SDavid du Colombier } 8918ccd4a63SDavid du Colombier 8928ccd4a63SDavid du Colombier int 8938ccd4a63SDavid du Colombier syschdir(char *path) 8948ccd4a63SDavid du Colombier { 8958ccd4a63SDavid du Colombier int n; 8968ccd4a63SDavid du Colombier 8978ccd4a63SDavid du Colombier starterror(); 8988ccd4a63SDavid du Colombier if(waserror()){ 8998ccd4a63SDavid du Colombier _syserror(); 9008ccd4a63SDavid du Colombier return -1; 9018ccd4a63SDavid du Colombier } 9028ccd4a63SDavid du Colombier n = _syschdir(path); 9038ccd4a63SDavid du Colombier enderror(); 9048ccd4a63SDavid du Colombier return n; 9058ccd4a63SDavid du Colombier } 9068ccd4a63SDavid du Colombier 9078ccd4a63SDavid du Colombier int 9088ccd4a63SDavid du Colombier sysclose(int fd) 9098ccd4a63SDavid du Colombier { 9108ccd4a63SDavid du Colombier int n; 9118ccd4a63SDavid du Colombier 9128ccd4a63SDavid du Colombier starterror(); 9138ccd4a63SDavid du Colombier if(waserror()){ 9148ccd4a63SDavid du Colombier _syserror(); 9158ccd4a63SDavid du Colombier return -1; 9168ccd4a63SDavid du Colombier } 9178ccd4a63SDavid du Colombier n = _sysclose(fd); 9188ccd4a63SDavid du Colombier enderror(); 9198ccd4a63SDavid du Colombier return n; 9208ccd4a63SDavid du Colombier } 9218ccd4a63SDavid du Colombier 9228ccd4a63SDavid du Colombier int 9238ccd4a63SDavid du Colombier syscreate(char *name, int mode, ulong perm) 9248ccd4a63SDavid du Colombier { 9258ccd4a63SDavid du Colombier int n; 9268ccd4a63SDavid du Colombier 9278ccd4a63SDavid du Colombier starterror(); 9288ccd4a63SDavid du Colombier if(waserror()){ 9298ccd4a63SDavid du Colombier _syserror(); 9308ccd4a63SDavid du Colombier return -1; 9318ccd4a63SDavid du Colombier } 9328ccd4a63SDavid du Colombier n = _syscreate(name, mode, perm); 9338ccd4a63SDavid du Colombier enderror(); 9348ccd4a63SDavid du Colombier return n; 9358ccd4a63SDavid du Colombier } 9368ccd4a63SDavid du Colombier 9378ccd4a63SDavid du Colombier int 9388ccd4a63SDavid du Colombier sysdup(int fd0, int fd1) 9398ccd4a63SDavid du Colombier { 9408ccd4a63SDavid du Colombier int n; 9418ccd4a63SDavid du Colombier 9428ccd4a63SDavid du Colombier starterror(); 9438ccd4a63SDavid du Colombier if(waserror()){ 9448ccd4a63SDavid du Colombier _syserror(); 9458ccd4a63SDavid du Colombier return -1; 9468ccd4a63SDavid du Colombier } 9478ccd4a63SDavid du Colombier n = _sysdup(fd0, fd1); 9488ccd4a63SDavid du Colombier enderror(); 9498ccd4a63SDavid du Colombier return n; 9508ccd4a63SDavid du Colombier } 9518ccd4a63SDavid du Colombier 9528ccd4a63SDavid du Colombier int 9538ccd4a63SDavid du Colombier sysfstat(int fd, uchar *buf, int n) 9548ccd4a63SDavid du Colombier { 9558ccd4a63SDavid du Colombier starterror(); 9568ccd4a63SDavid du Colombier if(waserror()){ 9578ccd4a63SDavid du Colombier _syserror(); 9588ccd4a63SDavid du Colombier return -1; 9598ccd4a63SDavid du Colombier } 9608ccd4a63SDavid du Colombier n = _sysfstat(fd, buf, n); 9618ccd4a63SDavid du Colombier enderror(); 9628ccd4a63SDavid du Colombier return n; 9638ccd4a63SDavid du Colombier } 9648ccd4a63SDavid du Colombier 9658ccd4a63SDavid du Colombier int 9668ccd4a63SDavid du Colombier sysfwstat(int fd, uchar *buf, int n) 9678ccd4a63SDavid du Colombier { 9688ccd4a63SDavid du Colombier starterror(); 9698ccd4a63SDavid du Colombier if(waserror()){ 9708ccd4a63SDavid du Colombier _syserror(); 9718ccd4a63SDavid du Colombier return -1; 9728ccd4a63SDavid du Colombier } 9738ccd4a63SDavid du Colombier n = _sysfwstat(fd, buf, n); 9748ccd4a63SDavid du Colombier enderror(); 9758ccd4a63SDavid du Colombier return n; 9768ccd4a63SDavid du Colombier } 9778ccd4a63SDavid du Colombier 9788ccd4a63SDavid du Colombier int 9798ccd4a63SDavid du Colombier sysmount(int fd, int afd, char *new, int flag, char *spec) 9808ccd4a63SDavid du Colombier { 9818ccd4a63SDavid du Colombier int n; 9828ccd4a63SDavid du Colombier 9838ccd4a63SDavid du Colombier starterror(); 9848ccd4a63SDavid du Colombier if(waserror()){ 9858ccd4a63SDavid du Colombier _syserror(); 9868ccd4a63SDavid du Colombier return -1; 9878ccd4a63SDavid du Colombier } 9888ccd4a63SDavid du Colombier n = _sysmount(fd, afd, new, flag, spec); 9898ccd4a63SDavid du Colombier enderror(); 9908ccd4a63SDavid du Colombier return n; 9918ccd4a63SDavid du Colombier } 9928ccd4a63SDavid du Colombier 9938ccd4a63SDavid du Colombier int 9948ccd4a63SDavid du Colombier sysunmount(char *old, char *new) 9958ccd4a63SDavid du Colombier { 9968ccd4a63SDavid du Colombier int n; 9978ccd4a63SDavid du Colombier 9988ccd4a63SDavid du Colombier starterror(); 9998ccd4a63SDavid du Colombier if(waserror()){ 10008ccd4a63SDavid du Colombier _syserror(); 10018ccd4a63SDavid du Colombier return -1; 10028ccd4a63SDavid du Colombier } 10038ccd4a63SDavid du Colombier n = _sysunmount(old, new); 10048ccd4a63SDavid du Colombier enderror(); 10058ccd4a63SDavid du Colombier return n; 10068ccd4a63SDavid du Colombier } 10078ccd4a63SDavid du Colombier 10088ccd4a63SDavid du Colombier int 10098ccd4a63SDavid du Colombier sysopen(char *name, int mode) 10108ccd4a63SDavid du Colombier { 10118ccd4a63SDavid du Colombier int n; 10128ccd4a63SDavid du Colombier 10138ccd4a63SDavid du Colombier starterror(); 10148ccd4a63SDavid du Colombier if(waserror()){ 10158ccd4a63SDavid du Colombier _syserror(); 10168ccd4a63SDavid du Colombier return -1; 10178ccd4a63SDavid du Colombier } 10188ccd4a63SDavid du Colombier n = _sysopen(name, mode); 10198ccd4a63SDavid du Colombier enderror(); 10208ccd4a63SDavid du Colombier return n; 10218ccd4a63SDavid du Colombier } 10228ccd4a63SDavid du Colombier 10238ccd4a63SDavid du Colombier int 10248ccd4a63SDavid du Colombier syspipe(int *fd) 10258ccd4a63SDavid du Colombier { 10268ccd4a63SDavid du Colombier int n; 10278ccd4a63SDavid du Colombier 10288ccd4a63SDavid du Colombier starterror(); 10298ccd4a63SDavid du Colombier if(waserror()){ 10308ccd4a63SDavid du Colombier _syserror(); 10318ccd4a63SDavid du Colombier return -1; 10328ccd4a63SDavid du Colombier } 10338ccd4a63SDavid du Colombier n = _syspipe(fd); 10348ccd4a63SDavid du Colombier enderror(); 10358ccd4a63SDavid du Colombier return n; 10368ccd4a63SDavid du Colombier } 10378ccd4a63SDavid du Colombier 10388ccd4a63SDavid du Colombier long 10398ccd4a63SDavid du Colombier syspread(int fd, void *buf, long n, vlong off) 10408ccd4a63SDavid du Colombier { 10418ccd4a63SDavid du Colombier starterror(); 10428ccd4a63SDavid du Colombier if(waserror()){ 10438ccd4a63SDavid du Colombier _syserror(); 10448ccd4a63SDavid du Colombier return -1; 10458ccd4a63SDavid du Colombier } 10468ccd4a63SDavid du Colombier n = _syspread(fd, buf, n, off); 10478ccd4a63SDavid du Colombier enderror(); 10488ccd4a63SDavid du Colombier return n; 10498ccd4a63SDavid du Colombier } 10508ccd4a63SDavid du Colombier 10518ccd4a63SDavid du Colombier long 10528ccd4a63SDavid du Colombier syspwrite(int fd, void *buf, long n, vlong off) 10538ccd4a63SDavid du Colombier { 10548ccd4a63SDavid du Colombier starterror(); 10558ccd4a63SDavid du Colombier if(waserror()){ 10568ccd4a63SDavid du Colombier _syserror(); 10578ccd4a63SDavid du Colombier return -1; 10588ccd4a63SDavid du Colombier } 10598ccd4a63SDavid du Colombier n = _syspwrite(fd, buf, n, off); 10608ccd4a63SDavid du Colombier enderror(); 10618ccd4a63SDavid du Colombier return n; 10628ccd4a63SDavid du Colombier } 10638ccd4a63SDavid du Colombier 10648ccd4a63SDavid du Colombier long 10658ccd4a63SDavid du Colombier sysread(int fd, void *buf, long n) 10668ccd4a63SDavid du Colombier { 10678ccd4a63SDavid du Colombier starterror(); 10688ccd4a63SDavid du Colombier if(waserror()){ 10698ccd4a63SDavid du Colombier _syserror(); 10708ccd4a63SDavid du Colombier return -1; 10718ccd4a63SDavid du Colombier } 10728ccd4a63SDavid du Colombier n = _syspread(fd, buf, n, (uvlong) ~0); 10738ccd4a63SDavid du Colombier enderror(); 10748ccd4a63SDavid du Colombier return n; 10758ccd4a63SDavid du Colombier } 10768ccd4a63SDavid du Colombier 10778ccd4a63SDavid du Colombier int 10788ccd4a63SDavid du Colombier sysremove(char *path) 10798ccd4a63SDavid du Colombier { 10808ccd4a63SDavid du Colombier int n; 10818ccd4a63SDavid du Colombier 10828ccd4a63SDavid du Colombier starterror(); 10838ccd4a63SDavid du Colombier if(waserror()){ 10848ccd4a63SDavid du Colombier _syserror(); 10858ccd4a63SDavid du Colombier return -1; 10868ccd4a63SDavid du Colombier } 10878ccd4a63SDavid du Colombier n = _sysremove(path); 10888ccd4a63SDavid du Colombier enderror(); 10898ccd4a63SDavid du Colombier return n; 10908ccd4a63SDavid du Colombier } 10918ccd4a63SDavid du Colombier 10928ccd4a63SDavid du Colombier vlong 10938ccd4a63SDavid du Colombier sysseek(int fd, vlong off, int whence) 10948ccd4a63SDavid du Colombier { 10958ccd4a63SDavid du Colombier starterror(); 10968ccd4a63SDavid du Colombier if(waserror()){ 10978ccd4a63SDavid du Colombier _syserror(); 10988ccd4a63SDavid du Colombier return -1; 10998ccd4a63SDavid du Colombier } 11008ccd4a63SDavid du Colombier off = _sysseek(fd, off, whence); 11018ccd4a63SDavid du Colombier enderror(); 11028ccd4a63SDavid du Colombier return off; 11038ccd4a63SDavid du Colombier } 11048ccd4a63SDavid du Colombier 11058ccd4a63SDavid du Colombier int 11068ccd4a63SDavid du Colombier sysstat(char *name, uchar *buf, int n) 11078ccd4a63SDavid du Colombier { 11088ccd4a63SDavid du Colombier starterror(); 11098ccd4a63SDavid du Colombier if(waserror()){ 11108ccd4a63SDavid du Colombier _syserror(); 11118ccd4a63SDavid du Colombier return -1; 11128ccd4a63SDavid du Colombier } 11138ccd4a63SDavid du Colombier n = _sysstat(name, buf, n); 11148ccd4a63SDavid du Colombier enderror(); 11158ccd4a63SDavid du Colombier return n; 11168ccd4a63SDavid du Colombier } 11178ccd4a63SDavid du Colombier 11188ccd4a63SDavid du Colombier long 11198ccd4a63SDavid du Colombier syswrite(int fd, void *buf, long n) 11208ccd4a63SDavid du Colombier { 11218ccd4a63SDavid du Colombier starterror(); 11228ccd4a63SDavid du Colombier if(waserror()){ 11238ccd4a63SDavid du Colombier _syserror(); 11248ccd4a63SDavid du Colombier return -1; 11258ccd4a63SDavid du Colombier } 11268ccd4a63SDavid du Colombier n = _syspwrite(fd, buf, n, (uvlong) ~0); 11278ccd4a63SDavid du Colombier enderror(); 11288ccd4a63SDavid du Colombier return n; 11298ccd4a63SDavid du Colombier } 11308ccd4a63SDavid du Colombier 11318ccd4a63SDavid du Colombier int 11328ccd4a63SDavid du Colombier syswstat(char *name, uchar *buf, int n) 11338ccd4a63SDavid du Colombier { 11348ccd4a63SDavid du Colombier starterror(); 11358ccd4a63SDavid du Colombier if(waserror()){ 11368ccd4a63SDavid du Colombier _syserror(); 11378ccd4a63SDavid du Colombier return -1; 11388ccd4a63SDavid du Colombier } 11398ccd4a63SDavid du Colombier n = _syswstat(name, buf, n); 11408ccd4a63SDavid du Colombier enderror(); 11418ccd4a63SDavid du Colombier return n; 11428ccd4a63SDavid du Colombier } 11438ccd4a63SDavid du Colombier 11448ccd4a63SDavid du Colombier void 11458ccd4a63SDavid du Colombier werrstr(char *f, ...) 11468ccd4a63SDavid du Colombier { 11478ccd4a63SDavid du Colombier char buf[ERRMAX]; 11488ccd4a63SDavid du Colombier va_list arg; 11498ccd4a63SDavid du Colombier 11508ccd4a63SDavid du Colombier va_start(arg, f); 11518ccd4a63SDavid du Colombier vsnprint(buf, sizeof buf, f, arg); 11528ccd4a63SDavid du Colombier va_end(arg); 11538ccd4a63SDavid du Colombier 11548ccd4a63SDavid du Colombier if(up->nerrlab) 11558ccd4a63SDavid du Colombier strecpy(up->errstr, up->errstr+ERRMAX, buf); 11568ccd4a63SDavid du Colombier else 11578ccd4a63SDavid du Colombier strecpy(up->syserrstr, up->syserrstr+ERRMAX, buf); 11588ccd4a63SDavid du Colombier } 11598ccd4a63SDavid du Colombier 11608ccd4a63SDavid du Colombier int 1161*0d601874SDavid du Colombier __errfmt(Fmt *fmt) 11628ccd4a63SDavid du Colombier { 11638ccd4a63SDavid du Colombier if(up->nerrlab) 11648ccd4a63SDavid du Colombier return fmtstrcpy(fmt, up->errstr); 11658ccd4a63SDavid du Colombier else 11668ccd4a63SDavid du Colombier return fmtstrcpy(fmt, up->syserrstr); 11678ccd4a63SDavid du Colombier } 11688ccd4a63SDavid du Colombier 11698ccd4a63SDavid du Colombier int 11708ccd4a63SDavid du Colombier errstr(char *buf, uint n) 11718ccd4a63SDavid du Colombier { 11728ccd4a63SDavid du Colombier char tmp[ERRMAX]; 11738ccd4a63SDavid du Colombier char *p; 11748ccd4a63SDavid du Colombier 11758ccd4a63SDavid du Colombier p = up->nerrlab ? up->errstr : up->syserrstr; 11768ccd4a63SDavid du Colombier memmove(tmp, p, ERRMAX); 11778ccd4a63SDavid du Colombier utfecpy(p, p+ERRMAX, buf); 11788ccd4a63SDavid du Colombier utfecpy(buf, buf+n, tmp); 11798ccd4a63SDavid du Colombier return strlen(buf); 11808ccd4a63SDavid du Colombier } 11818ccd4a63SDavid du Colombier 11828ccd4a63SDavid du Colombier int 11838ccd4a63SDavid du Colombier rerrstr(char *buf, uint n) 11848ccd4a63SDavid du Colombier { 11858ccd4a63SDavid du Colombier char *p; 11868ccd4a63SDavid du Colombier 11878ccd4a63SDavid du Colombier p = up->nerrlab ? up->errstr : up->syserrstr; 11888ccd4a63SDavid du Colombier utfecpy(buf, buf+n, p); 11898ccd4a63SDavid du Colombier return strlen(buf); 11908ccd4a63SDavid du Colombier } 11918ccd4a63SDavid du Colombier 11928ccd4a63SDavid du Colombier ulong 11938ccd4a63SDavid du Colombier _sysrendezvous(ulong arg0, ulong arg1) 11948ccd4a63SDavid du Colombier { 11958ccd4a63SDavid du Colombier ulong tag, val; 11968ccd4a63SDavid du Colombier Proc *p, **l; 11978ccd4a63SDavid du Colombier 11988ccd4a63SDavid du Colombier tag = arg0; 11998ccd4a63SDavid du Colombier l = &REND(up->rgrp, tag); 12008ccd4a63SDavid du Colombier up->rendval = ~0UL; 12018ccd4a63SDavid du Colombier 12028ccd4a63SDavid du Colombier lock(&up->rgrp->ref.lk); 12038ccd4a63SDavid du Colombier for(p = *l; p; p = p->rendhash) { 12048ccd4a63SDavid du Colombier if(p->rendtag == tag) { 12058ccd4a63SDavid du Colombier *l = p->rendhash; 12068ccd4a63SDavid du Colombier val = p->rendval; 12078ccd4a63SDavid du Colombier p->rendval = arg1; 12088ccd4a63SDavid du Colombier 12098ccd4a63SDavid du Colombier while(p->mach != 0) 12108ccd4a63SDavid du Colombier ; 12118ccd4a63SDavid du Colombier procwakeup(p); 12128ccd4a63SDavid du Colombier unlock(&up->rgrp->ref.lk); 12138ccd4a63SDavid du Colombier return val; 12148ccd4a63SDavid du Colombier } 12158ccd4a63SDavid du Colombier l = &p->rendhash; 12168ccd4a63SDavid du Colombier } 12178ccd4a63SDavid du Colombier 12188ccd4a63SDavid du Colombier /* Going to sleep here */ 12198ccd4a63SDavid du Colombier up->rendtag = tag; 12208ccd4a63SDavid du Colombier up->rendval = arg1; 12218ccd4a63SDavid du Colombier up->rendhash = *l; 12228ccd4a63SDavid du Colombier *l = up; 12238ccd4a63SDavid du Colombier up->state = Rendezvous; 12248ccd4a63SDavid du Colombier unlock(&up->rgrp->ref.lk); 12258ccd4a63SDavid du Colombier 12268ccd4a63SDavid du Colombier procsleep(); 12278ccd4a63SDavid du Colombier 12288ccd4a63SDavid du Colombier return up->rendval; 12298ccd4a63SDavid du Colombier } 12308ccd4a63SDavid du Colombier 12318ccd4a63SDavid du Colombier ulong 12328ccd4a63SDavid du Colombier sysrendezvous(ulong tag, ulong val) 12338ccd4a63SDavid du Colombier { 12348ccd4a63SDavid du Colombier ulong n; 12358ccd4a63SDavid du Colombier 12368ccd4a63SDavid du Colombier starterror(); 12378ccd4a63SDavid du Colombier if(waserror()){ 12388ccd4a63SDavid du Colombier _syserror(); 12398ccd4a63SDavid du Colombier return -1; 12408ccd4a63SDavid du Colombier } 12418ccd4a63SDavid du Colombier n = _sysrendezvous(tag, val); 12428ccd4a63SDavid du Colombier enderror(); 12438ccd4a63SDavid du Colombier return n; 12448ccd4a63SDavid du Colombier } 1245