plan 9 kernel history: overview | file list | diff list

1991/1109/port/devproc.c (diff list | history)

1991/1108/sys/src/9/port/devproc.c:4,91991/1109/sys/src/9/port/devproc.c:4,10 (short | long | prev | next)
1990/0227    
#include	"dat.h" 
#include	"fns.h" 
#include	"errno.h" 
1991/1109    
#include	"fcall.h" 
1990/0227    
 
#include	"devtab.h" 
 
1991/1108/sys/src/9/port/devproc.c:21,441991/1109/sys/src/9/port/devproc.c:22,39
1990/0227    
 
1991/0712    
#define	STATSIZE	(2*NAMELEN+12+6*12) 
1990/0227    
Dirtab procdir[]={ 
1990/11211    
	"ctl",		{Qctl},		0,			0600, 
	"mem",		{Qmem},		0,			0600, 
	"note",		{Qnote},	0,			0600, 
1991/1109    
	"ctl",		{Qctl},		0,			0000, 
	"mem",		{Qmem},		0,			0000, 
	"note",		{Qnote},	0,			0000, 
1990/11211    
	"notepg",	{Qnotepg},	0,			0200, 
	"proc",		{Qproc},	sizeof(Proc),		0600, 
1991/1109    
	"proc",		{Qproc},	sizeof(Proc),		0000, 
1991/0705    
	"segment",	{Qsegment},	0,			0400, 
1991/0807    
	"status",	{Qstatus},	STATSIZE,		0400, 
1990/11211    
	"text",		{Qtext},	0,			0600, 
1991/1109    
	"text",		{Qtext},	0,			0000, 
1990/0227    
}; 
 
1991/0705    
char *sname[]={ 			/* Segment type from portdat.h */ 
	"Text",  
	"Data",  
	"Bss",  
	"Stack",  
	"Shared",  
	"Phys", 
}; 
1991/1109    
/* Segment type from portdat.h */ 
char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys" }; 
1991/0705    
 
1990/0227    
/* 
1990/11211    
 * Qids are, in path: 
1991/1108/sys/src/9/port/devproc.c:54,651991/1109/sys/src/9/port/devproc.c:49,64
1990/1128    
#define	SLOT(q)	((((q).path&0x07FFFFFF0)>>QSHIFT)-1) 
1990/11211    
#define	PID(q)	((q).vers) 
1990/0227    
 
1991/1109    
void	procctlreq(Proc*, char*, int); 
int	procctlmemio(Proc*, ulong, int, void*, int); 
Chan   *procctlnotepg(Chan*, void *va, int n); 
 
1990/0227    
int 
procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) 
{ 
	Proc *p; 
	char buf[NAMELEN]; 
1991/0705    
	ulong pid, path; 
1991/1109    
	ulong pid, path, perm; 
1990/0227    
 
1990/11211    
	if(c->qid.path == CHDIR){ 
1990/0227    
		if(s >= conf.nproc) 
1991/1108/sys/src/9/port/devproc.c:69,751991/1109/sys/src/9/port/devproc.c:68,74
1990/0227    
		if(pid == 0) 
			return 0; 
		sprint(buf, "%d", pid); 
1990/11211    
		devdir(c, (Qid){CHDIR|((s+1)<<QSHIFT), pid}, buf, 0, CHDIR|0500, dp); 
1991/1109    
		devdir(c, (Qid){CHDIR|((s+1)<<QSHIFT), pid}, buf, 0, p->user, CHDIR|0500, dp); 
1990/0227    
		return 1; 
	} 
	if(s >= NPROC) 
1991/1108/sys/src/9/port/devproc.c:78,851991/1109/sys/src/9/port/devproc.c:77,89
1990/0227    
		panic("procgen"); 
	tab = &procdir[s]; 
1991/0705    
	path = c->qid.path&~(CHDIR|((1<<QSHIFT)-1));	/* slot component */ 
	devdir(c, (Qid){path|tab->qid.path, c->qid.vers}, 
1990/11211    
		tab->name, tab->length, tab->perm, dp); 
1991/1109    
 
	p = proctab(SLOT(c->qid)); 
	perm = tab->perm; 
	if(perm == 0) 
		perm = p->procmode; 
 
	devdir(c, (Qid){path|tab->qid.path, c->qid.vers}, tab->name, tab->length, p->user, perm, dp); 
1990/0227    
	return 1; 
} 
 
1991/1108/sys/src/9/port/devproc.c:218,2241991/1109/sys/src/9/port/devproc.c:222,239
1990/0227    
void 
procwstat(Chan *c, char *db) 
{ 
1990/11211    
	error(Eperm); 
1991/1109    
	Proc *p; 
	Dir d; 
 
	convM2D(db, &d); 
	p = proctab(SLOT(c->qid)); 
	if(p->pid != PID(c->qid)) 
		error(Eprocdied); 
 
	if(strcmp(u->p->user, p->user) != 0 && strcmp(u->p->user, eve) != 0) 
		error(Eperm); 
 
	p->procmode = d.mode&0777; 
1990/0227    
} 
 
void 
1991/1108/sys/src/9/port/devproc.c:232,2391991/1109/sys/src/9/port/devproc.c:247,252
1990/0227    
	char *a = va, *b; 
1991/0705    
	char statbuf[NSEG*32]; 
1990/0227    
	Proc *p; 
1991/0705    
	Pte *pte; 
	Segment *s; 
1990/0227    
	Page *pg; 
1990/0614    
	KMap *k; 
1991/0705    
	int i, j; 
1991/1108/sys/src/9/port/devproc.c:240,2541991/1109/sys/src/9/port/devproc.c:253,263
1990/0227    
	long l; 
	long pid; 
	User *up; 
1991/0705    
	ulong soff; 
	Segment *sg; 
1990/0227    
 
1990/11211    
	if(c->qid.path & CHDIR) 
1990/0227    
		return devdirread(c, a, n, 0, 0, procgen); 
 
	/* 
	 * BUG: should lock(&p->debug)? 
	 */ 
	p = proctab(SLOT(c->qid)); 
1990/11211    
	if(p->pid != PID(c->qid)) 
		error(Eprocdied); 
1991/1108/sys/src/9/port/devproc.c:260,2961991/1109/sys/src/9/port/devproc.c:269,276
1990/0227    
		 */ 
1991/0411    
		if(((offset+n)&~(BY2PG-1)) != (offset&~(BY2PG-1))) 
			n = BY2PG - (offset&(BY2PG-1)); 
1991/0705    
		s = seg(p, offset, 1); 
1990/0227    
		if(s){ 
1991/0705    
			if(p->pid!=PID(c->qid)){ 
				qunlock(&s->lk); 
1990/11211    
				error(Eprocdied); 
1990/0227    
			} 
1991/0705    
 
			soff = offset-s->base; 
			pte = s->map[soff/PTEMAPMEM]; 
			pg = 0; 
			if(pte) 
				pg = pte->pages[(soff&(PTEMAPMEM-1))/BY2PG]; 
                 
			s->steal++; 
			qunlock(&s->lk); 
			if(pagedout(pg)){ 
1991/0724    
				pprint("nonresident page addr %lux (complain to philw)\n", offset); 
1990/0227    
				memset(a, 0, n); 
			}else{ 
1990/0614    
				k = kmap(pg); 
				b = (char*)VA(k); 
1991/0411    
				memmove(a, b+(offset&(BY2PG-1)), n); 
1990/0614    
				kunmap(k); 
1990/0227    
			} 
1991/0705    
			qlock(&s->lk); 
			s->steal--; 
			qunlock(&s->lk); 
1990/0227    
			return n; 
		} 
		/* u area */ 
1991/0411    
		if(offset>=USERADDR && offset<USERADDR+BY2PG){ 
1991/1109    
		if(offset >= USERADDR && offset < USERADDR+BY2PG) { 
1991/0411    
			if(offset+n > USERADDR+BY2PG) 
				n = USERADDR+BY2PG - offset; 
1990/0227    
			pg = p->upage; 
1991/1108/sys/src/9/port/devproc.c:303,3241991/1109/sys/src/9/port/devproc.c:283,304
1990/0227    
			return n; 
		} 
 
		/* kernel memory.  BUG: shouldn't be so easygoing. BUG: mem mapping? */ 
1991/0411    
		if(offset>=KZERO && offset<KZERO+conf.npage0*BY2PG){ 
1991/1109    
		if(offset >= KZERO && offset < KZERO+conf.npage0*BY2PG){ 
1991/0411    
			if(offset+n > KZERO+conf.npage0*BY2PG) 
				n = KZERO+conf.npage0*BY2PG - offset; 
			memmove(a, (char*)offset, n); 
1990/0914    
			return n; 
1990/0227    
		} 
1991/1025    
		if(offset>=KZERO && offset<KZERO+conf.base1+conf.npage1*BY2PG){ 
1991/1109    
 
		if(offset >= KZERO && offset < KZERO+conf.base1+conf.npage1*BY2PG){ 
1991/1025    
			if(offset+n > KZERO+conf.base1+conf.npage1*BY2PG) 
				n = KZERO+conf.base1+conf.npage1*BY2PG - offset; 
			memmove(a, (char*)offset, n); 
			return n; 
		} 
1990/0227    
		return 0; 
		break; 
 
1991/1109    
		return procctlmemio(p, offset, n, va, 1); 
 
1990/0227    
	case Qnote: 
		lock(&p->debug); 
		if(waserror()){ 
1991/1108/sys/src/9/port/devproc.c:395,4011991/1109/sys/src/9/port/devproc.c:375,380
1991/0411    
procwrite(Chan *c, void *va, long n, ulong offset) 
1990/0227    
{ 
	Proc *p; 
1990/1110    
	Pgrp *pg; 
1990/0227    
	User *up; 
1990/0614    
	KMap *k; 
1990/0227    
	char buf[ERRLEN]; 
1991/1108/sys/src/9/port/devproc.c:404,4261991/1109/sys/src/9/port/devproc.c:383,392
1990/11211    
		error(Eisdir); 
1990/1110    
 
1990/1126    
	p = proctab(SLOT(c->qid)); 
1990/1110    
	/* 
	 * Special case: don't worry about process, just use remembered group 
	 */ 
1991/1109    
 
	/* Use the remembered pgrp id in the channel rather than the process pgrpid */ 
1990/1110    
	if(QID(c->qid) == Qnotepg){ 
1990/11211    
		pg = pgrptab(c->pgrpid.path-1); 
1991/0212    
		qlock(&pg->debug); 
1990/1110    
		if(waserror()){ 
1991/0212    
			qunlock(&pg->debug); 
1990/1110    
			nexterror(); 
		} 
1990/11211    
		if(pg->pgrpid != c->pgrpid.vers){ 
1991/0212    
			qunlock(&pg->debug); 
1990/1110    
  	  		goto Died; 
		} 
		pgrpnote(pg, va, n, NUser); 
1991/0614    
		poperror(); 
1991/0212    
		qunlock(&pg->debug); 
1991/1109    
		procctlnotepg(c, va, n); 
1990/1110    
		return n; 
	} 
 
1991/1108/sys/src/9/port/devproc.c:430,4661991/1109/sys/src/9/port/devproc.c:396,409
1990/0227    
		nexterror(); 
	} 
1990/11211    
	if(p->pid != PID(c->qid)) 
1990/0227    
    Died: 
1990/11211    
		error(Eprocdied); 
1990/0227    
 
	switch(QID(c->qid)){ 
1991/1109    
	case Qmem: 
		return procctlmemio(p, offset, n, va, 0); 
1990/0227    
	case Qctl: 
1991/0705    
		if(n >= 4 && strncmp(va, "exit", 4) == 0) { 
			if(p->state == Broken) { 
				ready(p); 
				break; 
			} 
		} 
1990/0227    
		else 
1991/0705    
		if(n >= 4 && strncmp(va, "stop", 4) == 0) { 
			p->procctl = Proc_stopme; 
			break; 
		} 
		else 
		if(n >= 5 && strncmp(va, "start", 5) == 0) { 
			if(p->state == Stopped) { 
				ready(p); 
				break; 
			} 
			errors("not stopped"); 
		} 
		else 
		if(n >= 4 && strncmp(va, "kill", 4) == 0) { 
1991/1108    
			postnote(p, 0, "sys: killed", NExit); 
1991/0705    
			p->procctl = Proc_exitme; 
			break; 
		} 
		error(Ebadctl); 
1991/1109    
		procctlreq(p, va, n); 
		return n; 
1990/0227    
	case Qnote: 
1990/0614    
		k = kmap(p->upage); 
		up = (User*)VA(k); 
1991/1108/sys/src/9/port/devproc.c:485,4891991/1109/sys/src/9/port/devproc.c:428,566
1990/0227    
	} 
1991/0614    
	poperror(); 
1990/0227    
	unlock(&p->debug); 
1991/1109    
	return n; 
} 
 
Chan * 
procctlnotepg(Chan *c, void *va, int n) 
{ 
	Pgrp *pg; 
 
	pg = pgrptab(c->pgrpid.path-1); 
	qlock(&pg->debug); 
	if(waserror()){ 
		qunlock(&pg->debug); 
		nexterror(); 
	} 
	if(pg->pgrpid != c->pgrpid.vers){ 
		qunlock(&pg->debug); 
		error(Eprocdied); 
	} 
	pgrpnote(pg, va, n, NUser); 
	poperror(); 
	qunlock(&pg->debug); 
} 
 
void 
procctlreq(Proc *p, char *va, int n) 
{ 
	if(n >= 4) { 
		if(strncmp(va, "exit", 4) == 0) { 
			if(p->state == Broken) 
				ready(p); 
			return; 
		} 
		if(strncmp(va, "stop", 4) == 0) { 
			p->procctl = Proc_stopme; 
			return; 
		} 
		if(strncmp(va, "kill", 4) == 0) { 
			postnote(p, 0, "sys: killed", NExit); 
			p->procctl = Proc_exitme; 
			return; 
		} 
	} 
 
	if(n >= 5 && strncmp(va, "start", 5) == 0) { 
		if(p->state != Stopped) 
			errors("not stopped"); 
		ready(p); 
		return; 
	} 
	error(Ebadctl); 
} 
 
int 
procctlmemio(Proc *p, ulong offset, int n, void *va, int read) 
{ 
	Pte **pte; 
	Page *pg; 
	KMap *k; 
	Segment *ps, *s; 
	ulong soff; 
	int i; 
	char *a = va, *b; 
 
	s = seg(p, offset, 1); 
	if(s == 0) 
		errors("not in address space"); 
 
	/* Revert a text segment to data */ 
	if(read == 0 && (s->type&SG_TYPE) == SG_TEXT) { 
		ps = newseg(SG_DATA, s->base, s->size); 
		ps->image = s->image; 
		incref(ps->image); 
		ps->fstart = s->fstart; 
		ps->flen = s->flen; 
 
		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); 
		p->seg[i] = ps; 
	} 
	else 
		qunlock(&s->lk); 
 
Again: 
	s = seg(p, offset, 1); 
	if(s == 0) 
		errors("not in address space"); 
 
	s->steal++; 
	soff = offset-s->base; 
	pte = &s->map[soff/PTEMAPMEM]; 
	if(*pte == 0) { 
		if(waserror()) { 
			s->steal--; 
			nexterror(); 
		} 
		if(fixfault(s, offset, read, 0) != 0) { 
			s->steal--; 
			poperror(); 
			goto Again; 
		} 
		poperror(); 
		if(*pte == 0) 
			panic("procctlmemio");  
	} 
	pg = (*pte)->pages[(soff&(PTEMAPMEM-1))/BY2PG]; 
	if(pagedout(pg)) { 
		if(waserror()) { 
			s->steal--; 
			nexterror(); 
		} 
		if(fixfault(s, offset, read, 0) != 0) { 
			s->steal--; 
			poperror(); 
			goto Again; 
		} 
		poperror(); 
		pg = (*pte)->pages[(soff&(PTEMAPMEM-1))/BY2PG]; 
		if(pg == 0) 
			panic("procctlmemio1"); 
	} 
 
	k = kmap(pg); 
	b = (char*)VA(k); 
	memmove(a, b+(offset&(BY2PG-1)), n); 
	kunmap(k); 
 
	s->steal--; 
	qunlock(&s->lk); 
1990/0227    
	return n; 
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)