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
unlockfgrp(Fgrp * f)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
growfd(Fgrp * f,int fd)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
findfreefd(Fgrp * f,int start)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
newfd(Chan * c)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
newfd2(int fd[2],Chan * c[2])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*
fdtochan(int fd,int mode,int chkmnt,int iref)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
openmode(ulong o)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
_sysfd2path(int fd,char * buf,uint nbuf)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
_syspipe(int fd[2])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
_sysdup(int fd0,int fd1)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
_sysopen(char * name,int mode)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
fdclose(int fd,int flag)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
_sysclose(int fd)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
unionread(Chan * c,void * va,long n)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
kread(int fd,void * buf,long n,vlong * offp)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
_syspread(int fd,void * buf,long n,vlong off)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
kwrite(int fd,void * buf,long nn,vlong * offp)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
sys_write(int fd,void * buf,long n)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
_syspwrite(int fd,void * buf,long n,vlong off)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
_sysseek(int fd,vlong off,int whence)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
validstat(uchar * s,int n)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
_sysfstat(int fd,void * buf,long n)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
_sysstat(char * name,void * buf,long n)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
_syschdir(char * name)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
bindmount(int ismount,int fd,int afd,char * arg0,char * arg1,ulong flag,char * spec)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
_sysbind(char * old,char * new,int flag)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
_sysmount(int fd,int afd,char * new,int flag,char * spec)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
_sysunmount(char * old,char * new)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
_syscreate(char * name,int mode,ulong perm)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
_sysremove(char * name)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
_syswstat(char * name,void * buf,long n)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
_sysfwstat(int fd,void * buf,long n)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
starterror(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
_syserror(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
enderror(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
sysbind(char * old,char * new,int flag)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
syschdir(char * path)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
sysclose(int fd)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
syscreate(char * name,int mode,ulong perm)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
sysdup(int fd0,int fd1)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
sysfstat(int fd,uchar * buf,int n)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
sysfwstat(int fd,uchar * buf,int n)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
sysmount(int fd,int afd,char * new,int flag,char * spec)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
sysunmount(char * old,char * new)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
sysopen(char * name,int mode)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
syspipe(int * fd)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
syspread(int fd,void * buf,long n,vlong off)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
syspwrite(int fd,void * buf,long n,vlong off)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
sysread(int fd,void * buf,long n)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
sysremove(char * path)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
sysseek(int fd,vlong off,int whence)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
sysstat(char * name,uchar * buf,int n)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
syswrite(int fd,void * buf,long n)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
syswstat(char * name,uchar * buf,int n)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
werrstr(char * f,...)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
__errfmt(Fmt * fmt)11610d601874SDavid 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
errstr(char * buf,uint n)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
rerrstr(char * buf,uint n)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
1192*ec59a3ddSDavid du Colombier void*
_sysrendezvous(void * arg0,void * arg1)1193*ec59a3ddSDavid du Colombier _sysrendezvous(void* arg0, void* arg1)
11948ccd4a63SDavid du Colombier {
1195*ec59a3ddSDavid du Colombier void *tag, *val;
11968ccd4a63SDavid du Colombier Proc *p, **l;
11978ccd4a63SDavid du Colombier
11988ccd4a63SDavid du Colombier tag = arg0;
1199*ec59a3ddSDavid du Colombier l = &REND(up->rgrp, (uintptr)tag);
1200*ec59a3ddSDavid du Colombier up->rendval = (void*)~0;
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
1231*ec59a3ddSDavid du Colombier void*
sysrendezvous(void * tag,void * val)1232*ec59a3ddSDavid du Colombier sysrendezvous(void *tag, void *val)
12338ccd4a63SDavid du Colombier {
1234*ec59a3ddSDavid du Colombier void *n;
12358ccd4a63SDavid du Colombier
12368ccd4a63SDavid du Colombier starterror();
12378ccd4a63SDavid du Colombier if(waserror()){
12388ccd4a63SDavid du Colombier _syserror();
1239*ec59a3ddSDavid du Colombier return (void*)~0;
12408ccd4a63SDavid du Colombier }
12418ccd4a63SDavid du Colombier n = _sysrendezvous(tag, val);
12428ccd4a63SDavid du Colombier enderror();
12438ccd4a63SDavid du Colombier return n;
12448ccd4a63SDavid du Colombier }
1245