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

📄 devproc.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"../port/error.h"#include	"ureg.h"enum{	Qctl,	Qdir,	Qfd,	Qfpregs,	Qkregs,	Qmem,	Qnote,	Qnoteid,	Qnotepg,	Qns,	Qproc,	Qregs,	Qsegment,	Qstatus,	Qtext,	Qwait,	Qprofile,};#define	STATSIZE	(2*NAMELEN+12+9*12)Dirtab procdir[] ={	"ctl",		{Qctl},		0,			0000,	"fd",		{Qfd},		0,			0000,	"fpregs",	{Qfpregs},	sizeof(FPsave),		0000,	"kregs",	{Qkregs},	sizeof(Ureg),		0440,	"mem",		{Qmem},		0,			0000,	"note",		{Qnote},	0,			0000,	"noteid",	{Qnoteid},	0,			0666,	"notepg",	{Qnotepg},	0,			0000,	"ns",		{Qns},		0,			0444,	"proc",		{Qproc},	0,			0400,	"regs",		{Qregs},	sizeof(Ureg),		0000,	"segment",	{Qsegment},	0,			0444,	"status",	{Qstatus},	STATSIZE,		0444,	"text",		{Qtext},	0,			0000,	"wait",		{Qwait},	0,			0400,	"profile",	{Qprofile},	0,			0400,};/* Segment type from portdat.h */char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Shdata", "Map" };/* * Qids are, in path: *	 4 bits of file type (qids above) *	23 bits of process slot number + 1 *	     in vers, *	32 bits of pid, for consistency checking * If notepg, c->pgrpid.path is pgrp slot, .vers is noteid. */#define	QSHIFT	5	/* location in qid of proc slot # */#define	QID(q)		(((q).path&0x0000001F)>>0)#define	SLOT(q)		((((q).path&0x07FFFFFE0)>>QSHIFT)-1)#define	PID(q)		((q).vers)#define	NOTEID(q)	((q).vers)void	procctlreq(Proc*, char*, int);int	procctlmemio(Proc*, ulong, int, void*, int);Chan*	proctext(Chan*, Proc*);Segment* txt2data(Proc*, Segment*);int	procstopped(void*);void	mntscan(Mntwalk*, Proc*);static intprocgen(Chan *c, Dirtab *tab, int, int s, Dir *dp){	Qid qid;	Proc *p;	Segment *q;	char buf[NAMELEN];	ulong pid, path, perm, len;	if(s == DEVDOTDOT){		c->qid.path = CHDIR;		devdir(c, c->qid, "#p", 0, eve, 0555, dp);		return 1;	}	if(c->qid.path == CHDIR){		if(s >= conf.nproc)			return -1;		p = proctab(s);		pid = p->pid;		if(pid == 0)			return 0;		sprint(buf, "%lud", pid);		qid = (Qid){CHDIR|((s+1)<<QSHIFT), pid};		devdir(c, qid, buf, 0, p->user, CHDIR|0555, dp);		return 1;	}	if(s >= nelem(procdir))		return -1;	if(tab)		panic("procgen");	tab = &procdir[s];	path = c->qid.path&~(CHDIR|((1<<QSHIFT)-1));	/* slot component */	p = proctab(SLOT(c->qid));	perm = tab->perm;	if(perm == 0)		perm = p->procmode;	len = tab->length;	switch(QID(c->qid)) {	case Qwait:		len = p->nwait * sizeof(Waitmsg);		break;	case Qprofile:		q = p->seg[TSEG];		if(q && q->profile) {			len = (q->top-q->base)>>LRESPROF;			len *= sizeof(*q->profile);		}		break;	}	qid = (Qid){path|tab->qid.path, c->qid.vers};	devdir(c, qid, tab->name, len, p->user, perm, dp);	return 1;}static voidprocinit(void){	if(conf.nproc >= (1<<(16-QSHIFT))-1)		print("warning: too many procs for devproc\n");}static Chan*procattach(char *spec){	return devattach('p', spec);}static intprocwalk(Chan *c, char *name){	return devwalk(c, name, 0, 0, procgen);}static voidprocstat(Chan *c, char *db){	devstat(c, db, 0, 0, procgen);}static Chan*procopen(Chan *c, int omode){	Proc *p;	Pgrp *pg;	Chan *tc;	int pid;	if(c->qid.path & CHDIR)		return devopen(c, omode, 0, 0, procgen);	p = proctab(SLOT(c->qid));	qlock(&p->debug);	if(waserror()){		qunlock(&p->debug);		nexterror();	}	pid = PID(c->qid);	if(p->pid != pid)		error(Eprocdied);	omode = openmode(omode);	switch(QID(c->qid)){	case Qtext:		if(omode != OREAD)			error(Eperm);		tc = proctext(c, p);		tc->offset = 0;		qunlock(&p->debug);		poperror();		return tc;	case Qproc:	case Qkregs:	case Qsegment:	case Qprofile:	case Qfd:		if(omode != OREAD)			error(Eperm);		break;	case Qctl:	case Qnote:	case Qnoteid:	case Qmem:	case Qstatus:	case Qwait:	case Qregs:	case Qfpregs:		break;	case Qns:		if(omode != OREAD)			error(Eperm);		c->aux = malloc(sizeof(Mntwalk));		break;	case Qnotepg:		pg = p->pgrp;		if(pg == nil)			error(Eprocdied);		if(omode!=OWRITE || pg->pgrpid == 1)			error(Eperm);		c->pgrpid.path = pg->pgrpid+1;		c->pgrpid.vers = p->noteid;		break;	default:		pprint("procopen %lux\n", c->qid);		error(Egreg);	}	/* Affix pid to qid */	if(p->state != Dead)		c->qid.vers = p->pid;	/* make sure the process slot didn't get reallocated while we were playing */	coherence();	if(p->pid != pid)		error(Eprocdied);	tc = devopen(c, omode, 0, 0, procgen);	qunlock(&p->debug);	poperror();	return tc;}static voidprocwstat(Chan *c, char *db){	Proc *p;	Dir d;	if(c->qid.path&CHDIR)		error(Eperm);	p = proctab(SLOT(c->qid));	if(waserror()){		qunlock(&p->debug);		nexterror();	}	qlock(&p->debug);	if(p->pid != PID(c->qid))		error(Eprocdied);	if(strcmp(up->user, p->user) != 0 && strcmp(up->user, eve) != 0)		error(Eperm);	convM2D(db, &d);	if(strcmp(d.uid, p->user) != 0){		if(strcmp(up->user, eve) != 0)			error(Eperm);		else {			strncpy(p->user, d.uid, sizeof(p->user));			p->user[sizeof(p->user)-1] = 0;		}	}	p->procmode = d.mode&0777;	poperror();	qunlock(&p->debug);}static intprocfds(Proc *p, char *va, int count, long offset){	Fgrp *f;	Chan *c;	int n, i;	qlock(&p->debug);	f = p->fgrp;	if(f == nil){		qunlock(&p->debug);		return 0;	}	lock(f);	if(waserror()){		unlock(f);		qunlock(&p->debug);		nexterror();	}	n = readstr(0, va, count, p->dot->name->s);	n += snprint(va+n, count-n, "\n");	for(i = 0; i <= f->maxfd; i++) {		c = f->fd[i];		if(c == nil)			continue;		n += snprint(va+n, count-n, "%3d %.2s %C %4ld %.8lux.%.8lud %8lld ",			i,			&"r w rw"[(c->mode&3)<<1],			devtab[c->type]->dc, c->dev,			c->qid.path, c->qid.vers,			c->offset);		n += readstr(0, va+n, count-n, c->name->s);		n += snprint(va+n, count-n, "\n");		if(offset > 0) {			offset -= n;			if(offset < 0) {				memmove(va, va+n+offset, -offset);				n = -offset;			}			else				n = 0;		}	}	unlock(f);	qunlock(&p->debug);	poperror();	return n;}static voidprocclose(Chan * c){	if(QID(c->qid) == Qns && c->aux != 0)		free(c->aux);}static voidint2flag(int flag, char *s){	if(flag == 0){		*s = '\0';		return;	}	*s++ = '-';	if(flag & MAFTER)		*s++ = 'a';	if(flag & MBEFORE)		*s++ = 'b';	if(flag & MCREATE)		*s++ = 'c';	if(flag & MCACHE)		*s++ = 'C';	*s = '\0';}static longprocread(Chan *c, void *va, long n, vlong off){	long l;	Proc *p;	Waitq *wq;	Ureg kur;	uchar *rptr;	Mntwalk *mw;	Segment *sg, *s;	char *a = va, *sps;	int i, j, rsize, pid;	char statbuf[NSEG*32], *srv, flag[10];	ulong offset = off;	if(c->qid.path & CHDIR)		return devdirread(c, a, n, 0, 0, procgen);	p = proctab(SLOT(c->qid));	if(p->pid != PID(c->qid))		error(Eprocdied);	switch(QID(c->qid)){	case Qmem:		if(offset < KZERO		|| (offset >= USTKTOP-USTKSIZE && offset < USTKTOP))			return procctlmemio(p, offset, n, va, 1);		/* Protect crypt key memory */		if(offset+n >= palloc.cmembase && offset < palloc.cmemtop)			error(Eperm);		/* validate physical kernel addresses */		if(offset < (ulong)end) {			if(offset+n > (ulong)end)				n = (ulong)end - offset;			memmove(a, (char*)offset, n);			return n;		}		if(offset >= conf.base0 && offset < conf.npage0){			if(offset+n > conf.npage0)				n = conf.npage0 - offset;			memmove(a, (char*)offset, n);			return n;		}		if(offset >= conf.base1 && offset < conf.npage1){			if(offset+n > conf.npage1)				n = conf.npage1 - offset;			memmove(a, (char*)offset, n);			return n;		}		error(Ebadarg);	case Qprofile:		s = p->seg[TSEG];		if(s == 0 || s->profile == 0)			error("profile is off");		i = (s->top-s->base)>>LRESPROF;		i *= sizeof(*s->profile);		if(offset >= i)			return 0;		if(offset+n > i)			n = i - offset;		memmove(a, ((char*)s->profile)+offset, n);		return n;	case Qnote:		qlock(&p->debug);		if(waserror()){			qunlock(&p->debug);			nexterror();		}		if(p->pid != PID(c->qid))			error(Eprocdied);		if(n < ERRLEN)			error(Etoosmall);		if(p->nnote == 0)			n = 0;		else {			memmove(va, p->note[0].msg, ERRLEN);			p->nnote--;			memmove(p->note, p->note+1, p->nnote*sizeof(Note));			n = ERRLEN;		}		if(p->nnote == 0)			p->notepending = 0;		poperror();		qunlock(&p->debug);		return n;	case Qproc:		if(offset >= sizeof(Proc))			return 0;		if(offset+n > sizeof(Proc))			n = sizeof(Proc) - offset;		memmove(a, ((char*)p)+offset, n);		return n;	case Qregs:		rptr = (uchar*)p->dbgreg;		rsize = sizeof(Ureg);		goto regread;	case Qkregs:		memset(&kur, 0, sizeof(Ureg));		setkernur(&kur, p);		rptr = (uchar*)&kur;		rsize = sizeof(Ureg);		goto regread;	case Qfpregs:		rptr = (uchar*)&p->fpsave;		rsize = sizeof(FPsave);	regread:		if(rptr == 0)			error(Enoreg);		if(offset >= rsize)			return 0;		if(offset+n > rsize)			n = rsize - offset;		memmove(a, rptr+offset, n);		return n;	case Qstatus:		if(offset >= STATSIZE)			return 0;		if(offset+n > STATSIZE)			n = STATSIZE - offset;		sps = p->psstate;		if(sps == 0)			sps = statename[p->state];		memset(statbuf, ' ', sizeof statbuf);		memmove(statbuf+0*NAMELEN, p->text, strlen(p->text));		memmove(statbuf+1*NAMELEN, p->user, strlen(p->user));		memmove(statbuf+2*NAMELEN, sps, strlen(sps));		j = 2*NAMELEN + 12;		for(i = 0; i < 6; i++) {			l = p->time[i];			if(i == TReal)				l = MACHP(0)->ticks - l;			l = TK2MS(l);			readnum(0, statbuf+j+NUMSIZE*i, NUMSIZE, l, NUMSIZE);		}		/* ignore stack, which is mostly non-existent */		l = 0;		for(i=1; i<NSEG; i++){			s = p->seg[i];			if(s)				l += s->top - s->base;		}		readnum(0, statbuf+j+NUMSIZE*6, NUMSIZE, l>>10, NUMSIZE);		readnum(0, statbuf+j+NUMSIZE*7, NUMSIZE, p->basepri, NUMSIZE);		readnum(0, statbuf+j+NUMSIZE*8, NUMSIZE, p->priority, NUMSIZE);		memmove(a, statbuf+offset, n);		return n;	case Qsegment:		j = 0;		for(i = 0; i < NSEG; i++) {			sg = p->seg[i];			if(sg == 0)				continue;			j += sprint(statbuf+j, "%-6s %c%c %.8lux %.8lux %4ld\n",				sname[sg->type&SG_TYPE],				sg->type&SG_RONLY ? 'R' : ' ',				sg->profile ? 'P' : ' ',				sg->base, sg->top, sg->ref);		}		if(offset >= j)			return 0;		if(offset+n > j)			n = j-offset;		if(n == 0 && offset == 0)			exhausted("segments");		memmove(a, &statbuf[offset], n);		return n;	case Qwait:		if(n < sizeof(Waitmsg))			error(Etoosmall);		if(!canqlock(&p->qwaitr))			error(Einuse);

⌨️ 快捷键说明

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