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

📄 devproc.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
📖 第 1 页 / 共 2 页
字号:
		qlock(&p->debug);		if(waserror()){			qunlock(&p->debug);			nexterror();		}		if(p->pid != PID(c->qid))			error(Eprocdied);		if(n < 1)	/* must accept at least the '\0' */			error(Etoosmall);		if(p->nnote == 0)			n = 0;		else {			m = strlen(p->note[0].msg) + 1;			if(m > n)				m = n;			memmove(va, p->note[0].msg, m);			((char*)va)[m-1] = '\0';			p->nnote--;			memmove(p->note, p->note+1, p->nnote*sizeof(Note));			n = m;		}		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*KNAMELEN, p->text, strlen(p->text));		memmove(statbuf+1*KNAMELEN, p->user, strlen(p->user));		memmove(statbuf+2*KNAMELEN, sps, strlen(sps));		j = 2*KNAMELEN + 12;		for(i = 0; i < 6; i++) {			l = p->time[i];			if(i == TReal)				l = msec() - 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(!canqlock(&p->qwaitr))			error(Einuse);		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();		n = snprint(a, n, "%d %lud %lud %lud %q",			wq->w.pid,			wq->w.time[TUser], wq->w.time[TSys], wq->w.time[TReal],			wq->w.msg);		free(wq);		return n;	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->path->s);			qunlock(&p->debug);			poperror();			return i;		}		int2flag(mw->cm->mflag, flag);		if(strcmp(mw->cm->to->path->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->path->s : srv,				mw->mh->from->path->s, mw->cm->spec? mw->cm->spec : "");			free(srv);		}else			i = snprint(a, n, "bind %s %s %s\n", flag,				mw->cm->to->path->s, mw->mh->from->path->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, m;	Proc *p, *t, *et;	char *a, *arg, buf[ERRMAX];	ulong offset = off;	a = va;	if(c->qid.type & QTDIR)		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 Qargs:		if(n == 0)			error(Eshort);		if(n >= ERRMAX)			error(Etoobig);		arg = malloc(n+1);		if(arg == nil)			error(Enomem);		memmove(arg, va, n);		m = n;		if(arg[m-1] != 0)			arg[m++] = 0;		free(p->args);		p->nargs = m;		p->args = arg;		p->setargs = 1;		break;	case Qmem:		if(p->state != Stopped)			error(Ebadctl);		n = procctlmemio(p, offset, n, va, 0);		break;	case Qregs:		if(offset >= sizeof(Ureg))			n = 0;		else 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))			n = 0;		else 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 >= ERRMAX-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(t->state == Dead)				continue;			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,	devshutdown,	procattach,	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->ref.lk);	i = s->image;	if(i == 0) {		unlock(&s->ref.lk);		error(Eprocdied);	}	unlock(&s->ref.lk);	lock(&i->ref.lk);	if(waserror()) {		unlock(&i->ref.lk);		nexterror();	}	tc = i->c;	if(tc == 0)		error(Eprocdied);	if(incref(&tc->ref) == 1 || (tc->flag&COPEN) == 0 || tc->mode!=OREAD) {		cclose(tc);		error(Eprocdied);	}	if(p->pid != PID(c->qid))		error(Eprocdied);	unlock(&i->ref.lk);	poperror();	return tc;}voidprocstopwait(Proc *p, int ctl){	int pid;	if(p->pdbg)		error(Einuse);	if(procstopped(p) || p->state == Broken)		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);}static voidprocctlcloseone(Proc *p, Fgrp *f, int fd){	Chan *c;	c = f->fd[fd];	if(c == nil)		return;	f->fd[fd] = nil;	unlock(&f->ref.lk);	qunlock(&p->debug);	cclose(c);	qlock(&p->debug);	lock(&f->ref.lk);}voidprocctlclosefiles(Proc *p, int all, int fd){	int i;	Fgrp *f;	f = p->fgrp;	if(f == nil)		error(Eprocdied);	lock(&f->ref.lk);	f->ref.ref++;	if(all)		for(i = 0; i < f->maxfd; i++)			procctlcloseone(p, f, i);	else		procctlcloseone(p, f, fd);	unlock(&f->ref.lk);	closefgrp(f);}voidprocctlreq(Proc *p, char *va, int n){	Segment *s;	int npc, pri;	Cmdbuf *cb;	Cmdtab *ct;	if(p->kp)	/* no ctl requests to kprocs */		error(Eperm);	cb = parsecmd(va, n);	if(waserror()){		free(cb);		nexterror();	}	ct = lookupcmd(cb, proccmd, nelem(proccmd));	switch(ct->index){	case CMclose:		procctlclosefiles(p, 0, atoi(cb->f[1]));		break;	case CMclosefiles:		procctlclosefiles(p, 1, 0);		break;	case CMhang:		p->hang = 1;		break;	case CMkill:		switch(p->state) {		case Broken:			unbreak(p);			break;		case Stopped:			p->procctl = Proc_exitme;			postnote(p, 0, "sys: killed", NExit);			ready(p);			break;		default:			p->procctl = Proc_exitme;			postnote(p, 0, "sys: killed", NExit);		}		break;	case CMnohang:		p->hang = 0;		break;	case CMnoswap:		p->noswap = 1;		break;	case CMpri:		pri = atoi(cb->f[1]);		if(pri > PriNormal && !iseve())			error(Eperm);		procpriority(p, pri, 0);		break;	case CMfixedpri:		pri = atoi(cb->f[1]);		if(pri > PriNormal && !iseve())			error(Eperm);		procpriority(p, pri, 1);		break;	case CMprivate:		p->privatemem = 1;		break;	case CMprofile:		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);		break;	case CMstart:		if(p->state != Stopped)			error(Ebadctl);		ready(p);		break;	case CMstartstop:		if(p->state != Stopped)			error(Ebadctl);		p->procctl = Proc_traceme;		ready(p);		procstopwait(p, Proc_traceme);		break;	case CMstartsyscall:		if(p->state != Stopped)			error(Ebadctl);		p->procctl = Proc_tracesyscall;		ready(p);		procstopwait(p, Proc_tracesyscall);		break;	case CMstop:		procstopwait(p, Proc_stopme);		break;	case CMwaitstop:		procstopwait(p, 0);		break;	case CMwired:		procwired(p, atoi(cb->f[1]));		break;	case CMtrace:		switch(cb->nf){		case 1:			p->trace ^= 1;			break;		case 2:			p->trace = (atoi(cb->f[1]) != 0);			break;		default:			error("args");		}		break;	}	poperror();	free(cb);}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 */	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->ref);	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->ref);	ps->fstart = s->fstart;	ps->flen = s->flen;	ps->flushme = 1;	return ps;}

⌨️ 快捷键说明

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