static Chan* dupopen(Chan *c, int omode) { Chan *f; int fd, twicefd; if(c->qid.type & QTDIR){ if(omode != 0) error(Eisdir); c->mode = 0; c->flag |= COPEN; c->offset = 0; return c; } if(c->qid.type & QTAUTH) error(Eperm); twicefd = c->qid.path - 1; fd = twicefd/2; if((twicefd & 1)){ /* ctl file */ f = c; f->mode = openmode(omode); f->flag |= COPEN; f->offset = 0; }else{ /* fd file */ f = fdtochan(up->env->fgrp, fd, openmode(omode), 0, 1); cclose(c); } if(omode & OCEXEC) f->flag |= CCEXEC; return f; }
static Chan* signopen(Chan *c, int omode) { if(c->qid.type & QTDIR) { if(omode != OREAD) error(Eisdir); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } switch((ulong)c->qid.path){ case Qctl: if(!iseve()) error(Eperm); break; case Qkey: if(omode != OREAD && !iseve()) error(Eperm); break; } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; }
static struct chan *ver_open(struct chan *c, int omode) { if (c->qid.type & QTDIR) { if (openmode(omode) != O_READ) error(EPERM, ERROR_FIXME); } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; }
static struct chan* regressopen(struct chan *c, int omode) { if(c->qid.type & QTDIR){ if(openmode(omode) != O_READ) error(EPERM, NULL); } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; }
void fscreate(Chan *c, char *name, int mode, ulong perm) { Dir *d; Cname *n; if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) error(Efilename); n = addelem(newcname(FS(c)->name->s), name); osenter(); FS(c)->fd = create(n->s, mode, perm); osleave(); if(FS(c)->fd < 0) { cnameclose(n); fserr(FS(c)); } d = dirfstat(FS(c)->fd); if(d == nil) { cnameclose(n); close(FS(c)->fd); FS(c)->fd = -1; fserr(FS(c)); } c->qid = d->qid; free(d); cnameclose(FS(c)->name); FS(c)->name = n; c->mode = openmode(mode); c->offset = 0; FS(c)->offset = 0; c->flag |= COPEN; }
/* * if the stream doesn't exist, create it */ static Chan* loopbackopen(Chan *c, int omode) { Loop *lb; if(c->qid.type & QTDIR){ if(omode != OREAD) error(Ebadarg); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } lb = c->aux; qlock(lb); if(TYPE(c->qid.path) == Qdata){ if(lb->link[ID(c->qid.path)].ref){ qunlock(lb); error(Einuse); } lb->link[ID(c->qid.path)].ref++; } qunlock(lb); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->iounit = qiomaxatomic; return c; }
static Chan* mouseopen(Chan *c, int omode) { switch((ulong)c->qid.path){ case Qdir: if(omode != OREAD) error(Eperm); break; case Qmouse: lock(&mouse.ref.lk); if(mouse.open){ unlock(&mouse.ref.lk); error(Einuse); } mouse.open = 1; mouse.ref.ref++; mouse.lastresize = mouse.resize; unlock(&mouse.ref.lk); break; case Qsnarf: if(omode == ORDWR) error(Eperm); /* one at a time please */ c->aux = nil; incref(&mouse.ref); break; default: incref(&mouse.ref); } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; }
struct chan *devopen(struct chan *c, int omode, struct dirtab *tab, int ntab, Devgen * gen) { int i; struct dir dir; dir.qid.path = 0; for (i = 0;; i++) { switch ((*gen) (c, NULL, tab, ntab, i, &dir)) { case -1: goto Return; case 0: break; case 1: if (c->qid.path == dir.qid.path) { devpermcheck(dir.uid, dir.mode, omode); goto Return; } break; } } Return: c->offset = 0; if ((c->qid.type & QTDIR) && !IS_RDONLY(omode)) error("Tried opening dir with non-read-only mode %o", omode); c->mode = openmode(omode); c->flag |= COPEN; return c; }
/* * if the stream doesn't exist, create it */ static Chan* pipeopen(Chan *c, int omode) { Pipe *p; if(c->qid.type & QTDIR){ if(omode != OREAD) error(Ebadarg); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } p = c->aux; qlock(p); switch(NETTYPE(c->qid.path)){ case Qdata0: p->qref[0]++; break; case Qdata1: p->qref[1]++; break; } qunlock(p); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->iounit = qiomaxatomic; return c; }
int syscreate(char *path, int mode, uint32_t perm) { ERRSTACK(2); int fd; struct chan *c; if (waserror()) { poperror(); return -1; } openmode(mode & ~O_EXCL); /* error check only; OEXCL okay here */ c = namec(path, Acreate, mode, perm); if (waserror()) { cclose(c); nexterror(); } fd = newfd(c, mode); /* 9ns mode is the O_FLAGS and perm is glibc mode */ if (fd < 0) error(-fd, ERROR_FIXME); poperror(); poperror(); return fd; }
void syscreate(Ar0* ar0, ...) { Proc *up = externup(); char *aname; int fd, omode, perm; Chan *c; va_list list; va_start(list, ar0); /* * int create(char* file, int omode, uint32_t perm); * should be * int create(char* file, int omode, int perm); */ aname = va_arg(list, char*); omode = va_arg(list, int); perm = va_arg(list, int); va_end(list); openmode(omode & ~OEXCL); /* error check only; OEXCL okay here */ c = nil; if(waserror()) { if(c != nil) cclose(c); nexterror(); } c = namec(validaddr(aname, 1, 0), Acreate, omode, perm); fd = newfd(c); if(fd < 0) error(Enofd); poperror(); ar0->i = fd; }
void sysopen(Ar0* ar0, ...) { Proc *up = externup(); va_list list; char *aname; int fd, omode; Chan *c; /* * int open(char* file, int omode); */ va_start(list, ar0); aname = va_arg(list, char*); omode = va_arg(list, int); va_end(list); openmode(omode); /* error check only */ c = nil; if(waserror()){ if(c != nil) cclose(c); nexterror(); } aname = validaddr(aname, 1, 0); c = namec(aname, Aopen, omode, 0); fd = newfd(c); if(fd < 0) error(Enofd); poperror(); ar0->i = fd; }
int syscreate(char *path, int mode, uint32_t perm) { ERRSTACK(2); int fd; struct chan *c; if (waserror()) { poperror(); return -1; } openmode(mode & ~OEXCL); /* error check only; OEXCL okay here */ c = namec(path, Acreate, mode, perm); if (waserror()) { cclose(c); nexterror(); } fd = newfd(c); if (fd < 0) error(Enofd); poperror(); poperror(); return fd; }
Chan* devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen) { int i; Dir dir; for(i=0;; i++) { switch((*gen)(c, nil, tab, ntab, i, &dir)){ case -1: goto Return; case 0: break; case 1: if(c->qid.path == dir.qid.path) { devpermcheck(dir.uid, dir.mode, omode); goto Return; } break; } } Return: c->offset = 0; if((c->qid.type&QTDIR) && omode!=OREAD) error(Eperm); c->mode = openmode(omode); c->flag |= COPEN; return c; }
static Chan* segmentopen(Chan *c, int omode) { Globalseg *g; switch(TYPE(c)){ case Qtopdir: case Qsegdir: if(omode != 0) error(Eisdir); break; case Qctl: case Qfree: g = getgseg(c); if(waserror()){ putgseg(g); nexterror(); } devpermcheck(g->uid, g->perm, omode); c->aux = g; poperror(); c->flag |= COPEN; break; case Qdata: g = getgseg(c); if(waserror()){ putgseg(g); nexterror(); } devpermcheck(g->uid, g->perm, omode); if(g->s == nil) error("segment not yet allocated"); if(g->kproc == nil){ qlock(&g->l); if(waserror()){ qunlock(&g->l); nexterror(); } if(g->kproc == nil){ g->cmd = Cnone; kproc(g->name, segmentkproc, g); docmd(g, Cstart); } poperror(); qunlock(&g->l); } c->aux = g; poperror(); c->flag |= COPEN; break; default: panic("segmentopen"); } c->mode = openmode(omode); c->offset = 0; return c; }
/* * if the stream doesn't exist, create it */ static struct chan *pipeopen(struct chan *c, int omode) { ERRSTACK(2); Pipe *p; if (c->qid.type & QTDIR) { if (omode & O_WRITE) error(EINVAL, "Can only open directories O_READ, mode is %o oct", omode); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } openmode(omode); /* check it */ p = c->aux; qlock(&p->qlock); if (waserror()) { qunlock(&p->qlock); nexterror(); } switch (NETTYPE(c->qid.path)) { case Qdata0: devpermcheck(p->user, p->pipedir[1].perm, omode); p->qref[0]++; break; case Qdata1: devpermcheck(p->user, p->pipedir[2].perm, omode); p->qref[1]++; break; } poperror(); qunlock(&p->qlock); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->iounit = qiomaxatomic; return c; }
static void rootcreate(struct chan *c, char *name, int omode, uint32_t perm) { struct dirtab *r = &roottab[c->qid.path], *newr; struct rootdata *rd = &rootdata[c->qid.path]; /* need to filter openmode so that it gets only the access-type bits */ omode = openmode(omode); c->mode = openmode(omode); printd("rootcreate: c %p, name %s, omode %o, perm %x\n", c, name, omode, perm); /* find an empty slot */ int path = c->qid.path; int newfile; newfile = createentry(path, name, omode, perm); c->qid = roottab[newfile].qid; /* need to update c */ rd->size++; if (newfile > rootmaxq) rootmaxq = newfile; printd("create: %s, newfile %d, dotdot %d, rootmaxq %d\n", name, newfile, rootdata[newfile].dotdot, rootmaxq); }
/* * if the stream doesn't exist, create it */ static Chan* pipeopen(Chan *c, int omode) { Pipe *p; if(c->qid.type & QTDIR){ if(omode != OREAD) error(Ebadarg); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } openmode(omode); /* check it */ p = c->aux; qlock(&p->l); if(waserror()){ qunlock(&p->l); nexterror(); } switch(NETTYPE(c->qid.path)){ case Qdata0: devpermcheck(p->user, p->pipedir[1].perm, omode); p->qref[0]++; break; case Qdata1: devpermcheck(p->user, p->pipedir[2].perm, omode); p->qref[1]++; break; } poperror(); qunlock(&p->l); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->iounit = qiomaxatomic; return c; }
static void fscreate(Chan *c, char *name, int mode, ulong perm) { int m; ulong t; wchar_t *newpath; Ufsinfo *uif; m = fsomode(mode&3); uif = c->aux; t = pathtype(uif->path); newpath = catpath(uif->path, name, nil); if(waserror()){ free(newpath); nexterror(); } if(perm & DMDIR) { wchar_t *p; DIR *d; if(m || t!=TPATH_FILE) error(Eperm); if(!CreateDirectory(newpath, NULL)) oserror(); d = malloc(sizeof(*d)); p = catpath(newpath, "*.*", nil); d->handle = FindFirstFile(p, &d->wfd); free(p); if(d->handle == INVALID_HANDLE_VALUE){ free(d); oserror(); } d->keep = 1; uif->dir = d; } else { uif->dir = nil; if((uif->fh = CreateFile( newpath, fsaccess(mode), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) oserror(); } free(uif->path); uif->path = newpath; poperror(); c->qid = wfdtoqid(newpath, nil); c->offset = 0; c->flag |= COPEN; c->mode = openmode(mode); }
static Chan* screenopen(Chan *c, int omode) { if ((ulong)c->qid.path == Qdss) { qlock(&dsslck); oscreen.open = 1; c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; } return c; }
static Chan* devlogfsopen(Chan *c, int omode) { int instance, qid, qt; omode = openmode(omode); SPLITPATH(c->qid.path, c->qid.type, instance, qid, qt); #ifdef CALLTRACE print("devlogfsopen(c = 0x%.8lux, omode = %o, instance = %d, qid = %d, qt = %d)\n", (ulong)c, omode, instance, qid, qt); #endif rlock(&devlogfslist.rwlock); if (waserror()) { runlock(&devlogfslist.rwlock); #ifdef CALLTRACE print("devlogfsopen(c = 0x%.8lux, omode = %o) - error %s\n", (ulong)c, omode, up->env->errstr); #endif nexterror(); } if (DATAQID(qid, qt)) { Devlogfs *d; d = devlogfsfind(instance); if (d == nil) error(Enodev); if (strcmp(up->env->user, eve) != 0) error(Eperm); if (qid == Qfs && d->state != BootOpen) error(Eperm); if (d->server == nil) { errorany(logfsservernew(d->lb, d->ll, is, d->openflags, d->logfstrace, &d->server)); d->state = NeedVersion; } c = devopen(c, omode, 0, 0, devlogfsgennolock); incref(&d->ref); c->aux = d; } else if (qid == Qctl || qid == Qusers) { if (strcmp(up->env->user, eve) != 0) error(Eperm); c = devopen(c, omode, 0, 0, devlogfsgennolock); } else c = devopen(c, omode, 0, 0, devlogfsgennolock); poperror(); runlock(&devlogfslist.rwlock); #ifdef CALLTRACE print("devlogfsopen(c = 0x%.8lux, omode = %o) - return\n", (ulong)c, omode); #endif return c; }
static Chan* rtcopen(Chan* c, int omode) { omode = openmode(omode); switch((ulong)c->qid.path){ case Qrtc: if(strcmp(up->user, eve)!=0 && omode!=OREAD) error(Eperm); break; } return devopen(c, omode, rtcdir, nelem(rtcdir), devgen); }
static Chan* i82365open(Chan *c, int omode) { if(c->qid.type & QTDIR){ if(omode != OREAD) error(Eperm); } else increfp(slot + SLOTNO(c)); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; }
static Chan* srvopen(Chan *c, int omode) { SrvFile *sf; openmode(omode); /* check it */ if(c->qid.type & QTDIR){ if(omode != OREAD) error(Eisdir); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } sf = c->aux; qlock(&dev.l); if(waserror()){ qunlock(&dev.l); nexterror(); } devpermcheck(sf->user, sf->perm, omode); if(omode&ORCLOSE && strcmp(sf->user, up->env->user) != 0) error(Eperm); if(sf->perm & DMEXCL && sf->opens != 0) error(Einuse); sf->opens++; if(omode&ORCLOSE) sf->flags |= SORCLOSE; poperror(); qunlock(&dev.l); c->offset = 0; c->flag |= COPEN; c->mode = openmode(omode); return c; }
static Chan* flashopen(Chan *c, int omode) { omode = openmode(omode); switch(TYPE(c->qid.path)){ case Qdata: case Qctl: if(flash.card[c->dev] == nil) error(Enodev); break; } return devopen(c, omode, nil, 0, flashgen); }
static Chan* envcreate(Chan *c, char *name, int omode, ulong) { Egrp *eg; Evalue *e; Evalue **ent; if(c->qid.type != QTDIR || !envwriteable(c)) error(Eperm); if(strlen(name) >= sizeof(up->genbuf)) error(Etoolong); omode = openmode(omode); eg = envgrp(c); wlock(eg); if(waserror()) { wunlock(eg); nexterror(); } if(envlookup(eg, name, -1) != nil) error(Eexist); e = smalloc(sizeof(Evalue)); e->name = smalloc(strlen(name)+1); strcpy(e->name, name); if(eg->nent == eg->ment){ eg->ment += 32; ent = smalloc(sizeof(eg->ent[0])*eg->ment); if(eg->nent) memmove(ent, eg->ent, sizeof(eg->ent[0])*eg->nent); free(eg->ent); eg->ent = ent; } e->qid.path = ++eg->path; e->qid.vers = 0; eg->vers++; eg->ent[eg->nent++] = e; c->qid = e->qid; wunlock(eg); poperror(); c->offset = 0; c->mode = omode; c->flag |= COPEN; return c; }
Chan* fsopen(Chan *c, int mode) { osenter(); FS(c)->fd = open(FS(c)->name->s, mode); osleave(); if(FS(c)->fd < 0) fserr(FS(c)); c->mode = openmode(mode); c->offset = 0; FS(c)->offset = 0; c->flag |= COPEN; return c; }
static Chan* envcreate(Chan *c, char *name, int omode, ulong) { Egrp *eg; Evalue *e; if(c->qid.type != QTDIR || !envwriteable(c)) error(Eperm); if(strlen(name) >= sizeof(up->genbuf)) error(Etoolong); omode = openmode(omode); eg = envgrp(c); wlock(eg); if(waserror()) { wunlock(eg); nexterror(); } if(envlookup(eg, name, -1) != nil) error(Eexist); if(eg->nent == eg->ment){ Evalue *tmp; eg->ment += DELTAENV; if((tmp = realloc(eg->ent, sizeof(eg->ent[0])*eg->ment)) == nil){ eg->ment -= DELTAENV; error(Enomem); } eg->ent = tmp; } eg->vers++; e = &eg->ent[eg->nent++]; e->value = nil; e->len = 0; e->name = smalloc(strlen(name)+1); strcpy(e->name, name); mkqid(&e->qid, ++eg->path, 0, QTFILE); c->qid = e->qid; wunlock(eg); poperror(); c->offset = 0; c->mode = omode; c->flag |= COPEN; return c; }
static Chan* fsopen(Chan *c, int mode) { char *path; int m; UnixFd *ufd; ufd = c->aux; if(Trace) print("fsopen %s %#x\n", ufd->path->s, mode); /* protect files whose path does not begin with allowed */ if(strncmp(ufd->path->s, canopen, strlen(canopen)) != 0) error(Eperm); if(mode & ~(OTRUNC|ORCLOSE|3)) error(Ebadarg); if((c->qid.type & QTDIR) && mode != OREAD) error(Eperm); if((c->qid.type&QTDIR) && mode != OREAD) error(Eperm); c->mode = openmode(mode); path = fspath(c, nil); if(c->qid.type & QTDIR){ ufd->dir = opendir(path); if(ufd->dir == nil){ free(path); oserror(); } ufd->diroffset = 0; ufd->nextde = nil; }else{ m = mode & 3; if(m == OEXEC) m = OREAD; if(mode & OTRUNC) m |= O_TRUNC; if((ufd->fd = open(path, m)) < 0 && opensocket(ufd, path) < 0){ free(path); oserror(); } } free(path); c->flag |= COPEN; return c; }
static Chan* wsopen(Chan *c, int omode) { if(c->qid.type & QTDIR){ if(omode != OREAD) error(Eperm); } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->aux = nil; if(c->qid.path == WSdataqid) c->aux = collect(); return c; }