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

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

1991/1109/sys/src/9/port/devproc.c:5,101991/1110/sys/src/9/port/devproc.c:5,11 (short | long | prev | next)
1990/0227    
#include	"fns.h" 
#include	"errno.h" 
1991/1109    
#include	"fcall.h" 
1991/1110    
#include	"ureg.h" 
1990/0227    
 
#include	"devtab.h" 
 
1991/1109/sys/src/9/port/devproc.c:51,571991/1110/sys/src/9/port/devproc.c:52,61
1990/0227    
 
1991/1109    
void	procctlreq(Proc*, char*, int); 
int	procctlmemio(Proc*, ulong, int, void*, int); 
Chan   *procctlnotepg(Chan*, void *va, int n); 
1991/1110    
Chan   *procctlnotepg(Chan*, void*, int); 
Chan   *proctext(Chan*, Proc*); 
Segment *txt2data(Proc*, Segment*); 
int	procstopped(void*); 
1991/1109    
 
1990/0227    
int 
procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) 
1991/1109/sys/src/9/port/devproc.c:145,1791991/1110/sys/src/9/port/devproc.c:149,168
1990/0227    
	p = proctab(SLOT(c->qid)); 
1990/1110    
	pg = p->pgrp; 
1990/11211    
	if(p->pid != PID(c->qid)) 
1990/0227    
    Died: 
1990/11211    
		error(Eprocdied); 
1991/1110    
 
1990/0227    
	omode = openmode(omode); 
 
	switch(QID(c->qid)){ 
	case Qtext: 
1991/0705    
		s = p->seg[TSEG]; 
		if(s==0 || p->state==Dead || s->image==0)  
1990/0227    
			goto Died; 
1991/0605    
                 
1991/0705    
		tc = s->image->c; 
1990/0227    
		if(tc == 0) 
			goto Died; 
1991/0605    
                 
1990/0227    
		if(incref(tc) == 0){ 
    Close: 
			close(tc); 
			goto Died; 
		} 
		if(!(tc->flag&COPEN) || tc->mode!=OREAD) 
			goto Close; 
1991/0605    
                 
1990/11211    
		if(p->pid != PID(c->qid)) 
1990/0227    
			goto Close; 
1991/0605    
                 
1991/1110    
		tc = proctext(c, p); 
1990/0227    
		tc->offset = 0; 
1991/1110    
 
1990/0227    
		return tc; 
1991/1110    
 
1990/0227    
	case Qctl: 
	case Qnote: 
1991/1110    
	case Qmem: 
1991/0705    
	case Qsegment: 
1990/0227    
		break; 
1990/1110    
 
1991/1109/sys/src/9/port/devproc.c:185,1911991/1110/sys/src/9/port/devproc.c:174,179
1990/1110    
		break; 
 
1990/0227    
	case Qdir: 
1990/0614    
	case Qmem: 
1990/0227    
	case Qproc: 
	case Qstatus: 
1990/1110    
		if(omode != OREAD) 
1991/1109/sys/src/9/port/devproc.c:195,2031991/1110/sys/src/9/port/devproc.c:183,190
1990/0227    
		pprint("unknown qid in devopen\n"); 
1990/11211    
		error(Egreg); 
1990/0227    
	} 
	/* 
	 * Affix pid to qid 
	 */ 
1991/1110    
 
	/* Affix pid to qid */ 
1990/0227    
	if(p->state != Dead) 
1990/11211    
		c->qid.vers = p->pid; 
1990/03081    
   done: 
1991/1109/sys/src/9/port/devproc.c:264,2751991/1110/sys/src/9/port/devproc.c:251,256
1990/0227    
 
	switch(QID(c->qid)){ 
	case Qmem: 
		/* 
		 * One page at a time 
		 */ 
1991/0411    
		if(((offset+n)&~(BY2PG-1)) != (offset&~(BY2PG-1))) 
			n = BY2PG - (offset&(BY2PG-1)); 
1991/0705    
                 
1991/1109    
		if(offset >= USERADDR && offset < USERADDR+BY2PG) { 
1991/0411    
			if(offset+n > USERADDR+BY2PG) 
				n = USERADDR+BY2PG - offset; 
1991/1109/sys/src/9/port/devproc.c:283,3021991/1110/sys/src/9/port/devproc.c:264,284
1990/0227    
			return n; 
		} 
 
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; 
1991/1110    
		if(offset >= KZERO) { 
			if(offset < KZERO+conf.npage0*BY2PG){ 
				if(offset+n > KZERO+conf.npage0*BY2PG) 
					n = KZERO+conf.npage0*BY2PG - offset; 
				memmove(a, (char*)offset, n); 
				return n; 
			} 
			if(offset < KZERO+conf.base1+conf.npage1*BY2PG){ 
				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    
		} 
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    
                 
1991/1109    
		return procctlmemio(p, offset, n, va, 1); 
 
1990/0227    
	case Qnote: 
1991/1109/sys/src/9/port/devproc.c:353,3581991/1110/sys/src/9/port/devproc.c:335,341
1990/0227    
		} 
1991/0411    
		memmove(a, statbuf+offset, n); 
1990/0227    
		return n; 
1991/1110    
 
1991/0705    
	case Qsegment: 
		j = 0; 
		for(i = 0; i < NSEG; i++) 
1991/1109/sys/src/9/port/devproc.c:378,3831991/1110/sys/src/9/port/devproc.c:361,370
1990/0227    
	User *up; 
1990/0614    
	KMap *k; 
1990/0227    
	char buf[ERRLEN]; 
1991/1110    
	Ureg *ur; 
	User *pxu; 
	Page *pg; 
	char *a = va, *b; 
1990/0227    
 
1990/11211    
	if(c->qid.path & CHDIR) 
		error(Eisdir); 
1991/1109/sys/src/9/port/devproc.c:400,4091991/1110/sys/src/9/port/devproc.c:387,418
1990/0227    
 
	switch(QID(c->qid)){ 
1991/1109    
	case Qmem: 
		return procctlmemio(p, offset, n, va, 0); 
1991/1110    
		if(p->state != Stopped) 
			errors("not stopped"); 
 
		if(offset >= USERADDR && offset < USERADDR+BY2PG) { 
			pg = p->upage; 
			if(pg==0 || p->pid!=PID(c->qid)) 
				error(Eprocdied); 
			k = kmap(pg); 
			b = (char*)VA(k); 
			pxu = (User*)b; 
			if(offset < (ulong)pxu->dbgreg || offset+n >= (ulong)pxu->dbgreg+sizeof(Ureg)) { 
				kunmap(k); 
				errors("bad u-area address"); 
			} 
			ur = (Ureg*)(b+((ulong)pxu->dbgreg-USERADDR)); 
			setregisters(ur, (char*)pxu+(offset-USERADDR), a, n); 
			kunmap(k); 
		} 
		else 
			n = procctlmemio(p, offset, n, va, 0); 
		break; 
 
1990/0227    
	case Qctl: 
1991/1109    
		procctlreq(p, va, n); 
		return n; 
1991/1110    
		break; 
 
1990/0227    
	case Qnote: 
1990/0614    
		k = kmap(p->upage); 
		up = (User*)VA(k); 
1991/1109/sys/src/9/port/devproc.c:422,4271991/1110/sys/src/9/port/devproc.c:431,437
1990/0227    
		if(!postnote(p, 0, buf, NUser)) 
1990/11211    
			error(Enonote); 
1990/0227    
		break; 
1991/1110    
 
1990/0227    
	default: 
		pprint("unknown qid in procwrite\n"); 
1990/11211    
		error(Egreg); 
1991/1109/sys/src/9/port/devproc.c:432,4371991/1110/sys/src/9/port/devproc.c:442,490
1991/1109    
} 
 
Chan * 
1991/1110    
proctext(Chan *c, Proc *p) 
{ 
	Chan *tc; 
	Image *i; 
	Segment *s; 
 
	s = p->seg[TSEG]; 
	if(s==0 || 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) { 
		close(tc); 
		error(Eprocdied); 
	} 
 
	if(p->pid != PID(c->qid)) 
		error(Eprocdied); 
 
	unlock(i); 
	poperror(); 
 
	return tc; 
} 
 
Chan * 
1991/1109    
procctlnotepg(Chan *c, void *va, int n) 
{ 
	Pgrp *pg; 
1991/1109/sys/src/9/port/devproc.c:452,4571991/1110/sys/src/9/port/devproc.c:505,538
1991/1109    
} 
 
void 
1991/1110    
procstopwait(Proc *p, int ctl) 
{ 
	int pid; 
 
	if(p->pdbg) 
		errors("debugged already"); 
	if(procstopped(p)) 
		return; 
 
	if(ctl != 0) 
		p->procctl = ctl; 
	p->pdbg = u->p; 
	pid = p->pid; 
	unlock(&p->debug); 
	u->p->psstate = "Stopwait"; 
	if(waserror()) { 
		p->pdbg = 0; 
		lock(&p->debug); 
		nexterror(); 
	} 
	sleep(&u->p->sleep, procstopped, p); 
	poperror(); 
	lock(&p->debug); 
	if(p->pid != pid) 
		error(Eprocdied); 
} 
 
void 
1991/1109    
procctlreq(Proc *p, char *va, int n) 
{ 
	if(n >= 4) { 
1991/1109/sys/src/9/port/devproc.c:461,4671991/1110/sys/src/9/port/devproc.c:542,548
1991/1109    
			return; 
		} 
		if(strncmp(va, "stop", 4) == 0) { 
			p->procctl = Proc_stopme; 
1991/1110    
			procstopwait(p, Proc_stopme); 
1991/1109    
			return; 
		} 
		if(strncmp(va, "kill", 4) == 0) { 
1991/1109/sys/src/9/port/devproc.c:469,4761991/1110/sys/src/9/port/devproc.c:550,574
1991/1109    
			p->procctl = Proc_exitme; 
			return; 
		} 
1991/1110    
		if(strncmp(va, "hang", 4) == 0) { 
			p->hang = 1; 
			return; 
		} 
1991/1109    
	} 
 
1991/1110    
	if(n >= 8 && strncmp(va, "waitstop", 8) == 0) { 
		procstopwait(p, 0); 
		return; 
	} 
  
	if(n >= 9 && strncmp(va, "startstop", 9) == 0) { 
		if(p->state != Stopped) 
			errors("not stopped"); 
		p->procctl = Proc_traceme; 
		ready(p); 
		procstopwait(p, Proc_traceme); 
		return; 
	} 
1991/1109    
	if(n >= 5 && strncmp(va, "start", 5) == 0) { 
		if(p->state != Stopped) 
			errors("not stopped"); 
1991/1109/sys/src/9/port/devproc.c:477,5261991/1110/sys/src/9/port/devproc.c:575,612
1991/1109    
		ready(p); 
		return; 
	} 
1991/1110    
 
1991/1109    
	error(Ebadctl); 
} 
 
int 
1991/1110    
procstopped(void *a) 
{ 
	Proc *p = a; 
	return p->state == Stopped; 
} 
 
int 
1991/1109    
procctlmemio(Proc *p, ulong offset, int n, void *va, int read) 
{ 
	Pte **pte; 
	Page *pg; 
	KMap *k; 
	Segment *ps, *s; 
1991/1110    
	Segment *s; 
1991/1109    
	ulong soff; 
	int i; 
	char *a = va, *b; 
 
1991/1110    
Again: 
1991/1109    
	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; 
1991/1110    
	if(offset+n >= s->top) 
		n = s->top-offset; 
1991/1109    
 
		for(i = 0; i < NSEG; i++) 
			if(p->seg[i] == s) 
				break; 
		if(p->seg[i] != s) 
			panic("segment gone"); 
1991/1110    
	if(read == 0 && (s->type&SG_TYPE) == SG_TEXT) 
		s = txt2data(p, s); 
1991/1109    
 
		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]; 
1991/1109/sys/src/9/port/devproc.c:557,5661991/1110/sys/src/9/port/devproc.c:643,687
1991/1109    
 
	k = kmap(pg); 
	b = (char*)VA(k); 
	memmove(a, b+(offset&(BY2PG-1)), n); 
1991/1110    
	if(read == 1) 
		memmove(a, b+(offset&(BY2PG-1)), n); 
	else 
		memmove(b+(offset&(BY2PG-1)), a, n); 
 
1991/1109    
	kunmap(k); 
 
	s->steal--; 
	qunlock(&s->lk); 
1991/1110    
 
	if(read == 0) 
		p->newtlb = 1; 
 
1990/0227    
	return n; 
1991/1110    
} 
 
Segment * 
txt2data(Proc *p, Segment *s) 
{ 
	Segment *ps; 
	int i; 
 
	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; 
 
	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; 
 
	return ps; 
1990/0227    
} 


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