コード例 #1
0
ファイル: devip.c プロジェクト: 99years/plan9
static void
ipclose(Chan* c)
{
	Fs *f;

	f = ipfs[c->dev];
	switch(TYPE(c->qid)) {
	default:
		break;
	case Qlog:
		if(c->flag & COPEN)
			netlogclose(f);
		break;
	case Qdata:
	case Qctl:
	case Qerr:
		if(c->flag & COPEN)
			closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
		break;
	case Qsnoop:
		if(c->flag & COPEN)
			decref(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers);
		break;
	}
	free(((IPaux*)c->aux)->owner);
	free(c->aux);
}
コード例 #2
0
ファイル: devip.c プロジェクト: 99years/plan9
void
closeconv(Conv *cv)
{
	Conv *nc;
	Ipmulti *mp;

	qlock(cv);

	if(--cv->inuse > 0) {
		qunlock(cv);
		return;
	}

	/* close all incoming calls since no listen will ever happen */
	for(nc = cv->incall; nc; nc = cv->incall){
		cv->incall = nc->next;
		closeconv(nc);
	}
	cv->incall = nil;

	kstrdup(&cv->owner, network);
	cv->perm = 0660;

	while((mp = cv->multi) != nil)
		ipifcremmulti(cv, mp->ma, mp->ia);

	cv->r = nil;
	cv->rgen = 0;
	cv->p->close(cv);
	cv->state = Idle;
	qunlock(cv);
}
コード例 #3
0
ファイル: devcmd.c プロジェクト: dalmonian/harvey
static void
cmdproc(void *a)
{
	Conv *c;
	int n = 0;
	char status[ERRMAX];
	void *t = NULL;

	c = a;
	qlock(&c->l);
	if(Debug)
		print("f[0]=%q f[1]=%q\n", c->cmd->f[0], c->cmd->f[1]);
	if(waserror()){
		if(Debug)
			print("failed: %q\n", up->errstr);
		kstrdup(&c->error, up->errstr);
		c->state = "Done";
		qunlock(&c->l);
//		Wakeup(&c->startr);
		pexit("cmdproc", 0);
	}
//	t = oscmd(c->cmd->f+1, c->nice, c->dir, c->fd);
//	if(t == nil)
//		oserror();
	c->child = t;	/* to allow oscmdkill */
	poperror();
	qunlock(&c->l);
//	Wakeup(&c->startr);
	if(Debug)
		print("started\n");

//	while(waserror())
//		oscmdkill(t);
//	osenter();
	mwait(&c->p->ac->icc->fn);

//	n = oscmdwait(t, status, sizeof(status));
//	osleave();
	if(n < 0){
//		oserrstr(up->genbuf, sizeof(up->genbuf));
		n = snprint(status, sizeof(status), "0 0 0 0 %q", up->genbuf);
	}
	qlock(&c->l);
	c->child = nil;
//	oscmdfree(t);
	if(Debug){
		status[n]=0;
		print("done %d %d %d: %q\n", c->fd[0], c->fd[1], c->fd[2], status);
	}
	if(c->inuse > 0){
		c->state = "Done";
		if(c->waitq != nil)
			qproduce(c->waitq, status, n);
	}else
		closeconv(c);
	qunlock(&c->l);
	pexit("", 0);
}
コード例 #4
0
ファイル: devip.c プロジェクト: Vykook/acme-sac
static void
ipclose(Chan *c)
{
	Fs *f;

	f = ipfs[c->dev];
	switch(TYPE(c->qid)) {
	case Qdata:
	case Qctl:
		if(c->flag & COPEN)
			closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
		break;
	}
}
コード例 #5
0
ファイル: devcmd.c プロジェクト: dalmonian/harvey
static void
cmdclose(Chan *c)
{
	Conv *cc;
	int r;

	if((c->flag & COPEN) == 0)
		return;

	switch(TYPE(c->qid)) {
	case Qctl:
	case Qalloc:
	case Qexec:
	case Qdata:
	case Qstderr:
	case Qwait:
		cc = cmd.conv[CONV(c->qid)];
		qlock(&cc->l);
		if(TYPE(c->qid) == Qdata){
			if(c->mode == OWRITE || c->mode == ORDWR)
				cmdfdclose(cc, 0);
			if(c->mode == OREAD || c->mode == ORDWR)
				cmdfdclose(cc, 1);
		}else if(TYPE(c->qid) == Qstderr)
			cmdfdclose(cc, 2);

		r = --cc->inuse;
		if(cc->child != nil){
			if(!cc->killed)
			if(r == 0 || (cc->killonclose && TYPE(c->qid) == Qctl)){
				// oscmdkill(cc->child);
				cc->killed = 1;
			}
		}else if(r == 0)
			closeconv(cc);

		qunlock(&cc->l);
		break;
	}
}
コード例 #6
0
ファイル: devip.c プロジェクト: 99years/plan9
static Chan*
ipopen(Chan* c, int omode)
{
	Conv *cv, *nc;
	Proto *p;
	int perm;
	Fs *f;

	perm = m2p[omode&3];

	f = ipfs[c->dev];

	switch(TYPE(c->qid)) {
	default:
		break;
	case Qndb:
		if(omode & (OWRITE|OTRUNC) && !iseve())
			error(Eperm);
		if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC))
			f->ndb[0] = 0;
		break;
	case Qlog:
		netlogopen(f);
		break;
	case Qiproute:
	case Qarp:
		if(omode != OREAD && !iseve())
			error(Eperm);
		break;
	case Qtopdir:
	case Qprotodir:
	case Qconvdir:
	case Qstatus:
	case Qremote:
	case Qlocal:
	case Qstats:
	case Qbootp:
	case Qipselftab:
		if(omode != OREAD)
			error(Eperm);
		break;
	case Qsnoop:
		if(omode != OREAD)
			error(Eperm);
		p = f->p[PROTO(c->qid)];
		cv = p->conv[CONV(c->qid)];
		if(strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
			error(Eperm);
		incref(&cv->snoopers);
		break;
	case Qclone:
		p = f->p[PROTO(c->qid)];
		qlock(p);
		if(waserror()){
			qunlock(p);
			nexterror();
		}
		cv = Fsprotoclone(p, ATTACHER(c));
		qunlock(p);
		poperror();
		if(cv == nil) {
			error(Enodev);
			break;
		}
		mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE);
		break;
	case Qdata:
	case Qctl:
	case Qerr:
		p = f->p[PROTO(c->qid)];
		qlock(p);
		cv = p->conv[CONV(c->qid)];
		qlock(cv);
		if(waserror()) {
			qunlock(cv);
			qunlock(p);
			nexterror();
		}
		if((perm & (cv->perm>>6)) != perm) {
			if(strcmp(ATTACHER(c), cv->owner) != 0)
				error(Eperm);
		 	if((perm & cv->perm) != perm)
				error(Eperm);

		}
		cv->inuse++;
		if(cv->inuse == 1){
			kstrdup(&cv->owner, ATTACHER(c));
			cv->perm = 0660;
		}
		qunlock(cv);
		qunlock(p);
		poperror();
		break;
	case Qlisten:
		cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
		if((perm & (cv->perm>>6)) != perm) {
			if(strcmp(ATTACHER(c), cv->owner) != 0)
				error(Eperm);
		 	if((perm & cv->perm) != perm)
				error(Eperm);

		}

		if(cv->state != Announced)
			error("not announced");

		if(waserror()){
			closeconv(cv);
			nexterror();
		}
		qlock(cv);
		cv->inuse++;
		qunlock(cv);

		nc = nil;
		while(nc == nil) {
			/* give up if we got a hangup */
			if(qisclosed(cv->rq))
				error("listen hungup");

			qlock(&cv->listenq);
			if(waserror()) {
				qunlock(&cv->listenq);
				nexterror();
			}

			/* wait for a connect */
			sleep(&cv->listenr, incoming, cv);

			qlock(cv);
			nc = cv->incall;
			if(nc != nil){
				cv->incall = nc->next;
				mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
				kstrdup(&cv->owner, ATTACHER(c));
			}
			qunlock(cv);

			qunlock(&cv->listenq);
			poperror();
		}
		closeconv(cv);
		poperror();
		break;
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}