Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/*
 *  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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
/*
 *  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;
}
Ejemplo n.º 6
0
/*
 *  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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
Archivo: devsrv.c Proyecto: 8l/inferno
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;
}
Ejemplo n.º 9
0
Archivo: devprog.c Proyecto: 8l/inferno
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;
}