Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/gnot/devproc.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname gnot/devproc.c 1990/03091
## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/devproc.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"

#include	"devtab.h"

enum{
	Qdir,
	Qctl,
	Qmem,
	Qnote,
	Qproc,
	Qstatus,
	Qtext,
};

Dirtab procdir[]={
	"ctl",		Qctl,		0,			0600,
	"mem",		Qmem,		0,			0600,
	"note",		Qnote,		0,			0600,
	"proc",		Qproc,		sizeof(Proc),		0600,
	"status",	Qstatus,	NAMELEN+12+6*12,	0600,
	"text",		Qtext,		0,			0600,
};

/*
 * Qids are, from bottom to top:
 *	 4 bits of file type (qids above)
 *	12 bits of process slot number + 1
 *	15 bits of pid, for consistency checking
 */
#define	NPROC	(sizeof procdir/sizeof(Dirtab))
#define	QSHIFT	4	/* location in qid of proc slot # */
#define	PIDSHIFT 16	/* location in qid of pid */
#define	PIDMASK	0x7FFF	/* low bits of pid used in qid */
#define	QID(q)	(((q)&0x0000000F)>>0)
#define	SLOT(q)	((((q)&0x0000FFF0)>>QSHIFT)-1)
#define	PID(q)	(((q)&0x7FFF0000)>>PIDSHIFT)

int
procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
{
	Proc *p;
	char buf[NAMELEN];
	ulong pid;

	if(c->qid == CHDIR){
		if(s >= conf.nproc)
			return -1;
		p = proctab(s);
		pid = p->pid;
		if(pid == 0)
			return 0;
		sprint(buf, "%d", pid);
		devdir(c, CHDIR|(pid<<PIDSHIFT)|((s+1)<<QSHIFT), buf, 0, CHDIR|0500, dp);
		return 1;
	}
	if(s >= NPROC)
		return -1;
	if(tab)
		panic("procgen");
	tab = &procdir[s];
	devdir(c, (~CHDIR)&(c->qid|tab->qid), tab->name, tab->length, tab->perm, dp);
	return 1;
}

void
procinit(void)
{
	if(conf.nproc >= (1<<(16-QSHIFT))-1)
		print("warning: too many procs for devproc\n");
}

void
procreset(void)
{
}

Chan*
procattach(char *spec)
{
	Chan *c;
	return devattach('p', spec);
}

Chan*
procclone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int
procwalk(Chan *c, char *name)
{
	return devwalk(c, name, 0, 0, procgen);
}

void
procstat(Chan *c, char *db)
{
	devstat(c, db, 0, 0, procgen);
}

Chan *
procopen(Chan *c, int omode)
{
	Proc *p;
	Orig *o;
	Chan *tc;

	if(c->qid == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
		goto done;
	}
	p = proctab(SLOT(c->qid));
	if((p->pid&PIDMASK) != PID(c->qid))
    Died:
		error(0, Eprocdied);
	omode = openmode(omode);

	switch(QID(c->qid)){
	case Qtext:
		o = p->seg[TSEG].o;
		if(o==0 || p->state==Dead)
			goto Died;
		tc = o->chan;
		if(tc == 0)
			goto Died;
		if(incref(tc) == 0){
    Close:
			close(tc);
			goto Died;
		}
		if(!(tc->flag&COPEN) || tc->mode!=OREAD)
			goto Close;
		if((p->pid&PIDMASK) != PID(c->qid))
			goto Close;
		qlock(tc);
		tc->offset = 0;
		qunlock(tc);
		return tc;
	case Qctl:
	case Qnote:
		break;
	case Qdir:
	case Qmem:
	case Qproc:
	case Qstatus:
		if(omode!=OREAD)
			error(0, Eperm);
		break;
	default:
		pprint("unknown qid in devopen\n");
		error(0, Egreg);
	}
	/*
	 * Affix pid to qid
	 */
	if(p->state != Dead)
		c->qid |= (p->pid&PIDMASK)<<PIDSHIFT;
   done:
	c->mode = omode;
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

void
proccreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
}

void
procremove(Chan *c)
{
	error(0, Eperm);
}

void
procwstat(Chan *c, char *db)
{
	error(0, Eperm);
}

void
procclose(Chan * c)
{
}

long
procread(Chan *c, void *va, long n)
{
	char *a = va, *b;
	char statbuf[2*NAMELEN+12+6*12];
	Proc *p;
	Seg *s;
	Orig *o;
	Page *pg;
	int i;
	long l;
	long pid;
	User *up;

	if(c->qid & CHDIR)
		return devdirread(c, a, n, 0, 0, procgen);

	/*
	 * BUG: should lock(&p->debug)?
	 */
	p = proctab(SLOT(c->qid));
	if((p->pid&PIDMASK) != PID(c->qid))
		error(0, Eprocdied);

	switch(QID(c->qid)){
	case Qmem:
		/*
		 * One page at a time
		 */
		if(((c->offset+n)&~(BY2PG-1)) != (c->offset&~(BY2PG-1)))
			n = BY2PG - (c->offset&(BY2PG-1));
		s = seg(p, c->offset);
		if(s){
			o = s->o;
			if(o == 0)
				error(0, Eprocdied);
			lock(o);
			if(s->o!=o || (p->pid&PIDMASK)!=PID(c->qid)){
				unlock(o);
				error(0, Eprocdied);
			}
			if(seg(p, c->offset) != s){
				unlock(o);
				error(0, Egreg);
			}
			pg = o->pte[(c->offset-o->va)>>PGSHIFT].page;
			unlock(o);
			if(pg == 0){
				pprint("nonresident page (complain to rob)\n");
				memset(a, 0, n);
			}else{
				b = (char*)(pg->pa|KZERO);
				memcpy(a, b+(c->offset&(BY2PG-1)), n);
			}
			return n;
		}

		/* u area */
		if(c->offset>=USERADDR && c->offset<=USERADDR+BY2PG){
			if(c->offset+n > USERADDR+BY2PG)
				n = USERADDR+BY2PG - c->offset;
			pg = p->upage;
			if(pg==0 || (p->pid&PIDMASK)!=PID(c->qid))
				error(0, Eprocdied);
			b = (char*)(pg->pa|KZERO);
			memcpy(a, b+(c->offset-USERADDR), n);
			return n;
		}

		/* kernel memory.  BUG: shouldn't be so easygoing. BUG: mem mapping? */
		if(c->offset>=KZERO && c->offset<KZERO+conf.npage*BY2PG){
			if(c->offset+n > KZERO+conf.npage*BY2PG)
				n = KZERO+conf.npage*BY2PG - c->offset;
			memcpy(a, (char*)c->offset, n);
			return n;
		}
		return 0;
		break;

	case Qnote:
		lock(&p->debug);
		if(waserror()){
			unlock(&p->debug);
			nexterror();
		}
		if((p->pid&PIDMASK) != PID(c->qid))
			error(0, Eprocdied);
		up = (User*)(p->upage->pa|KZERO);
		if(up->p != p){
			pprint("note read u/p mismatch");
			error(0, Egreg);
		}
		if(n < ERRLEN)
			error(0, Etoosmall);
		if(up->nnote == 0)
			n = 0;
		else{
			memcpy(va, up->note[0].msg, ERRLEN);
			up->nnote--;
			memcpy(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
			n = ERRLEN;
		}
		unlock(&p->debug);
		return n;

	case Qproc:
		if(c->offset >= sizeof(Proc))
			return 0;
		if(c->offset+n > sizeof(Proc))
			n = sizeof(Proc) - c->offset;
		memcpy(a, ((char*)p)+c->offset, n);
		return n;

	case Qstatus:
		if(c->offset >= sizeof statbuf)
			return 0;
		if(c->offset+n > sizeof statbuf)
			n = sizeof statbuf - c->offset;
		sprint(statbuf, "%-27s %-27s %-11s ", p->text, p->pgrp->user, statename[p->state]);
		for(i=0; i<6; i++){
			l = p->time[i];
			if(i == TReal)
				l = MACHP(0)->ticks - l;
			l *= MS2HZ;
			readnum(0, statbuf+2*NAMELEN+12+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
		}
		memcpy(a, statbuf+c->offset, n);
		return n;
	}
	error(0, Egreg);
}


long
procwrite(Chan *c, void *va, long n)
{
	Proc *p;
	User *up;
	char buf[ERRLEN];

	if(c->qid & CHDIR)
		error(0, Eisdir);
	p = proctab(SLOT(c->qid));
	lock(&p->debug);
	if(waserror()){
		unlock(&p->debug);
		nexterror();
	}
	if((p->pid&PIDMASK) != PID(c->qid))
    Died:
		error(0, Eprocdied);

	switch(QID(c->qid)){
	case Qctl:
		if(p->state==Broken && n>=4 && strncmp(va, "exit", 4)==0)
			ready(p);
		else
			error(0, Ebadctl);
		break;
	case Qnote:
		up = (User*)(p->upage->pa|KZERO);
		if(up->p != p){
			pprint("note write u/p mismatch");
			error(0, Egreg);
		}
		if(n >= ERRLEN-1)
			error(0, Etoobig);
		if(n>=4 && strncmp(va, "sys:", 4)==0)
			error(0, Ebadarg);
		memcpy(buf, va, n);
		buf[n] = 0;
		if(!postnote(p, 0, buf, NUser))
			error(0, Enonote);
		break;
	default:
		pprint("unknown qid in procwrite\n");
		error(0, Egreg);
	}
	unlock(&p->debug);
	return n;
}

void
procuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void
procerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}
.
## diffname gnot/devproc.c 1990/05313
## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/devproc.c /n/bootesdump/1990/05313/sys/src/9/68020/devproc.c
243c
				pprint("nonresident page addr %lux (complain to rob)\n", c->offset);
.
240c
			pte = &o->pte[(c->offset-o->va)>>PGSHIFT];
			if(s->mod){
				opte = pte;
				while(pte = pte->nextmod)	/* assign = */
					if(pte->proc == p)
						break;
				if(pte == 0)
					pte = opte;
			}
			pg = pte->page;
.
203a
	PTE *pte, *opte;
.
## diffname gnot/devproc.c 1990/06021
## diff -e /n/bootesdump/1990/05313/sys/src/9/68020/devproc.c /n/bootesdump/1990/06021/sys/src/9/68020/devproc.c
369a
		kunmap(k);
.
366a
			kunmap(k);
.
365c
		k = kmap(p->upage);
		up = (User*)k->va;
.
342a
	KMap *k;
.
306a
		kunmap(k);
.
293a
			kunmap(k);
.
292c
		k = kmap(p->upage);
		up = (User*)k->va;
.
275,277c
		if(c->offset>=KZERO && c->offset<KZERO+conf.npage0*BY2PG){
			if(c->offset+n > KZERO+conf.npage0*BY2PG)
				n = KZERO+conf.npage0*BY2PG - c->offset;
.
270a
			kunmap(k);
.
269c
			k = kmap(pg);
			b = (char*)k->va;
.
257a
				kunmap(k);
.
256c
				k = kmap(pg);
				b = (char*)k->va;
.
203a
	KMap *k;
.
## diffname gnot/devproc.c 1990/06111
## diff -e /n/bootesdump/1990/06021/sys/src/9/68020/devproc.c /n/bootesdump/1990/06111/sys/src/9/68020/devproc.c
336c
			l = TK2MS(l);
.
## diffname gnot/devproc.c 1990/0614
## diff -e /n/bootesdump/1990/06111/sys/src/9/68020/devproc.c /n/bootesdump/1990/0614/sys/src/9/68020/devproc.c
375c
		up = (User*)VA(k);
.
298c
		up = (User*)VA(k);
.
273c
			b = (char*)VA(k);
.
258c
				b = (char*)VA(k);
.
## diffname gnot/devproc.c 1990/0617
## diff -e /n/bootesdump/1990/0614/sys/src/9/68020/devproc.c /n/bootesdump/1990/0617/sys/src/9/68020/devproc.c
266c
		if(c->offset>=USERADDR && c->offset<USERADDR+BY2PG){
.
## diffname gnot/devproc.c 1990/1106
## diff -e /n/bootesdump/1990/0617/sys/src/9/68020/devproc.c /n/bootesdump/1990/1106/sys/src/9/68020/devproc.c
355a

	/*
	 * Special case: don't worry about process, just use remembered group
	 */
	if(QID(c->qid) == Qnotepg){
		pg = pgrptab(SLOT(c->pgrpid));
		lock(&pg->debug);
		if(waserror()){
			unlock(&pg->debug);
			nexterror();
		}
		if((pg->pgrpid&PIDMASK) != PID(c->pgrpid)){
			unlock(&pg->debug);
  	  		goto Died;
		}
		pgrpnote(pg, va, n, NUser);
		unlock(&pg->debug);
		return n;
	}

.
349a
	Pgrp *pg;
.
153c
		if(omode != OREAD)
.
148a

	case Qnotepg:
		if(omode != OWRITE)
			error(0, Eperm);
		c->pgrpid = (pg->pgrpid<<PIDSHIFT)|((pg->index+1)<<QSHIFT);
		break;

.
119a
	pg = p->pgrp;
.
110a
	Pgrp *pg;
.
23a
	"notepg",	Qnotepg,	0,			0200,
.
14a
	Qnotepg,
.
## diffname gnot/devproc.c 1990/1115
## diff -e /n/bootesdump/1990/1106/sys/src/9/68020/devproc.c /n/bootesdump/1990/1115/sys/src/9/68020/devproc.c
155c
		if(omode!=OWRITE || pg->pgrpid==1)	/* easy to do by mistake */
.
## diffname gnot/devproc.c 1990/11211
## diff -e /n/bootesdump/1990/1115/sys/src/9/68020/devproc.c /n/bootesdump/1990/11211/sys/src/9/68020/devproc.c
429,440d
425c
		error(Egreg);
.
421c
			error(Enonote);
.
417c
			error(Ebadarg);
.
415c
			error(Etoobig);
.
411c
			error(Egreg);
.
403c
			error(Ebadctl);
.
396c
		error(Eprocdied);
.
394c
	if(p->pid != PID(c->qid))
.
379c
		if(pg->pgrpid != c->pgrpid.vers){
.
373c
		pg = pgrptab(c->pgrpid.path-1);
.
366,367c
	if(c->qid.path & CHDIR)
		error(Eisdir);
.
353c
	error(Egreg);
.
316c
			error(Etoosmall);
.
313c
			error(Egreg);
.
306,307c
		if(p->pid != PID(c->qid))
			error(Eprocdied);
.
281,282c
			if(pg==0 || p->pid!=PID(c->qid))
				error(Eprocdied);
.
251c
				error(Egreg);
.
247c
				error(Eprocdied);
.
245c
			if(s->o!=o || p->pid!=PID(c->qid)){
.
243c
				error(Eprocdied);
.
229,230c
	if(p->pid != PID(c->qid))
		error(Eprocdied);
.
222c
	if(c->qid.path & CHDIR)
.
198c
	error(Eperm);
.
192c
	error(Eperm);
.
186c
	error(Eperm);
.
175c
		c->qid.vers = p->pid;
.
169c
		error(Egreg);
.
165c
			error(Eperm);
.
156,157c
			error(Eperm);
		c->pgrpid.path = pg->index+1;
		c->pgrpid.vers = pg->pgrpid;
.
144c
		if(p->pid != PID(c->qid))
.
126c
		error(Eprocdied);
.
124c
	if(p->pid != PID(c->qid))
.
119c
			error(Eperm);
.
117c
	if(c->qid.path == CHDIR){
.
68c
	devdir(c, (Qid){(~CHDIR)&(c->qid.path|tab->qid.path), c->qid.vers},
		tab->name, tab->length, tab->perm, dp);
.
60c
		devdir(c, (Qid){CHDIR|((s+1)<<QSHIFT), pid}, buf, 0, CHDIR|0500, dp);
.
52c
	if(c->qid.path == CHDIR){
.
39,43c
#define	QID(q)	(((q).path&0x0000000F)>>0)
#define	SLOT(q)	((((q).path&0x0FFFFFFF0)>>QSHIFT)-1)
#define	PID(q)	((q).vers)
.
34,35c
 *	24 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 pgrpid.
.
32c
 * Qids are, in path:
.
22,28c
	"ctl",		{Qctl},		0,			0600,
	"mem",		{Qmem},		0,			0600,
	"note",		{Qnote},	0,			0600,
	"notepg",	{Qnotepg},	0,			0200,
	"proc",		{Qproc},	sizeof(Proc),		0600,
	"status",	{Qstatus},	NAMELEN+12+6*12,	0600,
	"text",		{Qtext},	0,			0600,
.
7a
/* BUG mips only TAKE IT OUT */
#include	"io.h"

.
## diffname gnot/devproc.c 1990/1126
## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devproc.c /n/bootesdump/1990/1126/sys/src/9/68020/devproc.c
393d
373a
	p = proctab(SLOT(c->qid));
.
## diffname gnot/devproc.c 1990/1128
## diff -e /n/bootesdump/1990/1126/sys/src/9/68020/devproc.c /n/bootesdump/1990/1128/sys/src/9/68020/devproc.c
45c
#define	SLOT(q)	((((q).path&0x07FFFFFF0)>>QSHIFT)-1)
.
37c
 *	23 bits of process slot number + 1
.
8,10d
## diffname gnot/devproc.c 1990/1210 # deleted
## diff -e /n/bootesdump/1990/1128/sys/src/9/68020/devproc.c /n/bootesdump/1990/1210/sys/src/9/68020/devproc.c
1,431d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].