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; }
/* * called by segattach() */ static Segment* globalsegattach(Proc *p, char *name) { int x; Globalseg *g; Segment *s; g = nil; if(waserror()){ unlock(&globalseglock); nexterror(); } lock(&globalseglock); for(x = 0; x < nelem(globalseg); x++){ g = globalseg[x]; if(g != nil && strcmp(g->name, name) == 0) break; } if(x == nelem(globalseg)){ unlock(&globalseglock); poperror(); return nil; } devpermcheck(g->uid, g->perm, ORDWR); s = g->s; if(s == nil) error("global segment not assigned a virtual address"); if(isoverlap(p, s->base, s->top - s->base) != nil) error("overlaps existing segment"); incref(s); unlock(&globalseglock); poperror(); return s; }
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; }
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; }
/* * 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; }
/* * 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 Chan* srvopen(Chan *c, int omode) { Srv *sp; if(c->qid.type == QTDIR){ if(omode & ORCLOSE) error(Eperm); if(omode != OREAD) error(Eisdir); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } qlock(&srvlk); if(waserror()){ qunlock(&srvlk); nexterror(); } sp = srvlookup(nil, c->qid.path); if(sp == 0 || sp->chan == 0) error(Eshutdown); if(omode&OTRUNC) error("srv file already exists"); if(openmode(omode)!=sp->chan->mode && sp->chan->mode!=ORDWR) error(Eperm); devpermcheck(sp->owner, sp->perm, omode); cclose(c); c = sp->chan; incref(c); c->offset = 0; qunlock(&srvlk); poperror(); 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* progopen(Chan *c, int omode) { Prog *p; Osenv *o; Progctl *ctl; int perm; if(c->qid.type & QTDIR) return devopen(c, omode, 0, 0, proggen); acquire(); if (waserror()) { release(); nexterror(); } p = progpid(PID(c->qid)); if(p == nil) error(Ethread); o = p->osenv; perm = progdir[QID(c->qid)-1].perm; if((perm & 7) == 0) perm = (perm|(perm>>3)|(perm>>6)) & o->pgrp->progmode; devpermcheck(o->user, perm, omode); omode = openmode(omode); switch(QID(c->qid)){ default: error(Egreg); case Qnsgrp: case Qpgrp: case Qtext: case Qstatus: case Qstack: case Qctl: case Qfd: case Qexception: break; case Qwait: c->aux = qopen(1024, Qmsg, nil, nil); if(c->aux == nil) error(Enomem); o->childq = c->aux; break; case Qns: c->aux = malloc(sizeof(Mntwalk)); if(c->aux == nil) error(Enomem); break; case Qheap: if(SECURE || p->group->flags&Pprivatemem || omode != ORDWR) error(Eperm); c->aux = malloc(sizeof(Heapqry)); if(c->aux == nil) error(Enomem); break; case Qdbgctl: if(SECURE || p->group->flags&Pprivatemem || omode != ORDWR) error(Eperm); ctl = malloc(sizeof(Progctl)); if(ctl == nil) error(Enomem); ctl->q = qopen(1024, Qmsg, nil, nil); if(ctl->q == nil) { free(ctl); error(Enomem); } ctl->bpts = nil; ctl->ref = 1; c->aux = ctl; break; } if(p->state != Pexiting) c->qid.vers = p->pid; poperror(); release(); c->offset = 0; c->mode = omode; c->flag |= COPEN; return c; }