⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devproc.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 2 页
字号:
		if(waserror()) {			qunlock(&p->qwaitr);			nexterror();		}		lock(&p->exl);		if(up == p && p->nchild == 0 && p->waitq == 0) {			unlock(&p->exl);			error(Enochild);		}		pid = p->pid;		while(p->waitq == 0) {			unlock(&p->exl);			sleep(&p->waitr, haswaitq, p);			if(p->pid != pid)				error(Eprocdied);			lock(&p->exl);		}		wq = p->waitq;		p->waitq = wq->next;		p->nwait--;		unlock(&p->exl);		qunlock(&p->qwaitr);		poperror();		memmove(a, &wq->w, sizeof(Waitmsg));		free(wq);		return sizeof(Waitmsg);	case Qns:		qlock(&p->debug);		if(waserror()){			qunlock(&p->debug);			nexterror();		}		if(p->pgrp == nil || p->pid != PID(c->qid))			error(Eprocdied);		mw = c->aux;		if(mw->cddone){			qunlock(&p->debug);			poperror();			return 0;		}		mntscan(mw, p);		if(mw->mh == 0){			mw->cddone = 1;			i = snprint(a, n, "cd %s\n", p->dot->name->s);			qunlock(&p->debug);			poperror();			return i;		}		int2flag(mw->cm->flag, flag);		if(strcmp(mw->cm->to->name->s, "#M") == 0){			srv = srvname(mw->cm->to->mchan);			i = snprint(a, n, "mount %s %s %s %.*s\n", flag,				srv==nil? mw->cm->to->mchan->name->s : srv,				mw->mh->from->name->s, NAMELEN, mw->cm->spec);			free(srv);		}else			i = snprint(a, n, "bind %s %s %s\n", flag,				mw->cm->to->name->s, mw->mh->from->name->s);		qunlock(&p->debug);		poperror();		return i;	case Qnoteid:		return readnum(offset, va, n, p->noteid, NUMSIZE);	case Qfd:		return procfds(p, va, n, offset);	}	error(Egreg);	return 0;		/* not reached */}voidmntscan(Mntwalk *mw, Proc *p){	Pgrp *pg;	Mount *t;	Mhead *f;	int nxt, i;	ulong last, bestmid;	pg = p->pgrp;	rlock(&pg->ns);	nxt = 0;	bestmid = ~0;	last = 0;	if(mw->mh)		last = mw->cm->mountid;	for(i = 0; i < MNTHASH; i++) {		for(f = pg->mnthash[i]; f; f = f->hash) {			for(t = f->mount; t; t = t->next) {				if(mw->mh == 0 ||				  (t->mountid > last && t->mountid < bestmid)) {					mw->cm = t;					mw->mh = f;					bestmid = mw->cm->mountid;					nxt = 1;				}			}		}	}	if(nxt == 0)		mw->mh = 0;	runlock(&pg->ns);}static longprocwrite(Chan *c, void *va, long n, vlong off){	int id;	Proc *p, *t, *et;	char *a, buf[ERRLEN];	ulong offset = off;	a = va;	if(c->qid.path & CHDIR)		error(Eisdir);	p = proctab(SLOT(c->qid));	/* Use the remembered noteid in the channel rather	 * than the process pgrpid	 */	if(QID(c->qid) == Qnotepg) {		pgrpnote(NOTEID(c->pgrpid), va, n, NUser);		return n;	}	qlock(&p->debug);	if(waserror()){		qunlock(&p->debug);		nexterror();	}	if(p->pid != PID(c->qid))		error(Eprocdied);	switch(QID(c->qid)){	case Qmem:		if(p->state != Stopped)			error(Ebadctl);		n = procctlmemio(p, offset, n, va, 0);		break;	case Qregs:		if(offset >= sizeof(Ureg))			return 0;		if(offset+n > sizeof(Ureg))			n = sizeof(Ureg) - offset;		if(p->dbgreg == 0)			error(Enoreg);		setregisters(p->dbgreg, (char*)(p->dbgreg)+offset, va, n);		break;	case Qfpregs:		if(offset >= sizeof(FPsave))			return 0;		if(offset+n > sizeof(FPsave))			n = sizeof(FPsave) - offset;		memmove((uchar*)&p->fpsave+offset, va, n);		break;	case Qctl:		procctlreq(p, va, n);		break;	case Qnote:		if(p->kp)			error(Eperm);		if(n >= ERRLEN-1)			error(Etoobig);		memmove(buf, va, n);		buf[n] = 0;		if(!postnote(p, 0, buf, NUser))			error("note not posted");		break;	case Qnoteid:		id = atoi(a);		if(id == p->pid) {			p->noteid = id;			break;		}		t = proctab(0);		for(et = t+conf.nproc; t < et; t++) {			if(id == t->noteid) {				if(strcmp(p->user, t->user) != 0)					error(Eperm);				p->noteid = id;				break;			}		}		if(p->noteid != id)			error(Ebadarg);		break;	default:		pprint("unknown qid in procwrite\n");		error(Egreg);	}	poperror();	qunlock(&p->debug);	return n;}Dev procdevtab = {	'p',	"proc",	devreset,	procinit,	procattach,	devclone,	procwalk,	procstat,	procopen,	devcreate,	procclose,	procread,	devbread,	procwrite,	devbwrite,	devremove,	procwstat,};Chan*proctext(Chan *c, Proc *p){	Chan *tc;	Image *i;	Segment *s;	s = p->seg[TSEG];	if(s == 0)		error(Enonexist);	if(p->state==Dead)		error(Eprocdied);	lock(s);	i = s->image;	if(i == 0) {		unlock(s);		error(Eprocdied);	}	unlock(s);	lock(i);	if(waserror()) {		unlock(i);		nexterror();	}	tc = i->c;	if(tc == 0)		error(Eprocdied);	if(incref(tc) == 1 || (tc->flag&COPEN) == 0 || tc->mode!=OREAD) {		cclose(tc);		error(Eprocdied);	}	if(p->pid != PID(c->qid))		error(Eprocdied);	unlock(i);	poperror();	return tc;}voidprocstopwait(Proc *p, int ctl){	int pid;	if(p->pdbg)		error(Einuse);	if(procstopped(p))		return;	if(ctl != 0)		p->procctl = ctl;	p->pdbg = up;	pid = p->pid;	qunlock(&p->debug);	up->psstate = "Stopwait";	if(waserror()) {		p->pdbg = 0;		qlock(&p->debug);		nexterror();	}	sleep(&up->sleep, procstopped, p);	poperror();	qlock(&p->debug);	if(p->pid != pid)		error(Eprocdied);}voidprocctlfgrp(Fgrp *f){	int i;	Chan *c;	lock(f);	f->ref++;	for(i = 0; i < f->maxfd; i++) {		c = f->fd[i];		if(c != 0) {			f->fd[i] = 0;			unlock(f);			cclose(c);			lock(f);		}	}	unlock(f);	closefgrp(f);}voidprocctlreq(Proc *p, char *va, int n){	Segment *s;	int i, npc;	char buf[NAMELEN];	if(n > NAMELEN)		n = NAMELEN;	strncpy(buf, va, n);	if(strncmp(buf, "stop", 4) == 0)		procstopwait(p, Proc_stopme);	else	if(strncmp(buf, "kill", 4) == 0) {		switch(p->state) {		case Broken:			unbreak(p);			break;		case Stopped:			postnote(p, 0, "sys: killed", NExit);			p->procctl = Proc_exitme;			ready(p);			break;		default:			postnote(p, 0, "sys: killed", NExit);			p->procctl = Proc_exitme;		}	}	else	if(strncmp(buf, "hang", 4) == 0)		p->hang = 1;	else	if(strncmp(buf, "nohang", 6) == 0)		p->hang = 0;	else	if(strncmp(buf, "waitstop", 8) == 0)		procstopwait(p, 0);	else	if(strncmp(buf, "startstop", 9) == 0) {		if(p->state != Stopped)			error(Ebadctl);		p->procctl = Proc_traceme;		ready(p);		procstopwait(p, Proc_traceme);	}	else	if(strncmp(buf, "start", 5) == 0) {		if(p->state != Stopped)			error(Ebadctl);		ready(p);	}	else	if(strncmp(buf, "closefiles", 10) == 0){		qlock(&p->debug);		if(waserror()){			qunlock(&p->debug);			nexterror();		}		if(p->fgrp == nil)			error(Eprocdied);		procctlfgrp(p->fgrp);		qunlock(&p->debug);		poperror();	}	else	if(strncmp(buf, "pri", 3) == 0) {		if(n < 4)			error(Ebadctl);		i = atoi(buf+4);		if(i < 0)			i = 0;		if(i >= Nrq)			i = Nrq - 1;		if(i > p->basepri && !iseve())			error(Eperm);		p->basepri = i;	}	else	if(strncmp(buf, "wired", 5) == 0) {		if(n < 6)			error(Ebadctl);		i = atoi(buf+6);		procwired(p, i);	}	else	if(strncmp(buf, "profile", 7) == 0) {		s = p->seg[TSEG];		if(s == 0 || (s->type&SG_TYPE) != SG_TEXT)			error(Ebadctl);		if(s->profile != 0)			free(s->profile);		npc = (s->top-s->base)>>LRESPROF;		s->profile = malloc(npc*sizeof(*s->profile));		if(s->profile == 0)			error(Enomem);	}	else		error(Ebadctl);}intprocstopped(void *a){	Proc *p = a;	return p->state == Stopped;}intprocctlmemio(Proc *p, ulong offset, int n, void *va, int read){	KMap *k;	Pte *pte;	Page *pg;	Segment *s;	ulong soff, l;	char *a = va, *b;	for(;;) {		s = seg(p, offset, 1);		if(s == 0)			error(Ebadarg);		if(offset+n >= s->top)			n = s->top-offset;		if(!read && (s->type&SG_TYPE) == SG_TEXT)			s = txt2data(p, s);		s->steal++;		soff = offset-s->base;		if(waserror()) {			s->steal--;			nexterror();		}		if(fixfault(s, offset, read, 0) == 0)			break;		poperror();		s->steal--;	}	poperror();	pte = s->map[soff/PTEMAPMEM];	if(pte == 0)		panic("procctlmemio");	pg = pte->pages[(soff&(PTEMAPMEM-1))/BY2PG];	if(pagedout(pg))		panic("procctlmemio1");	l = BY2PG - (offset&(BY2PG-1));	if(n > l)		n = l;	k = kmap(pg);	if(waserror()) {		s->steal--;		kunmap(k);		nexterror();	}	b = (char*)VA(k);	b += offset&(BY2PG-1);	if(read == 1)		memmove(a, b, n);	/* This can fault */	else		memmove(b, a, n);	kunmap(k);	poperror();	/* Ensure the process sees text page changes */	if(s->flushme)		memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));	s->steal--;	if(read == 0)		p->newtlb = 1;	return n;}Segment*txt2data(Proc *p, Segment *s){	int i;	Segment *ps;	ps = newseg(SG_DATA, s->base, s->size);	ps->image = s->image;	incref(ps->image);	ps->fstart = s->fstart;	ps->flen = s->flen;	ps->flushme = 1;	qlock(&p->seglock);	for(i = 0; i < NSEG; i++)		if(p->seg[i] == s)			break;	if(p->seg[i] != s)		panic("segment gone");	qunlock(&s->lk);	putseg(s);	qlock(&ps->lk);	p->seg[i] = ps;	qunlock(&p->seglock);	return ps;}Segment*data2txt(Segment *s){	Segment *ps;	ps = newseg(SG_TEXT, s->base, s->size);	ps->image = s->image;	incref(ps->image);	ps->fstart = s->fstart;	ps->flen = s->flen;	ps->flushme = 1;	return ps;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -