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

1991/0705/port/sysproc.c (diff list | history)

1991/0619/sys/src/9/port/sysproc.c:21,391991/0705/sys/src/9/port/sysproc.c:21,39 (short | long | prev | next)
1990/0227    
sysfork(ulong *arg) 
{ 
	Proc *p; 
	Seg *s; 
1991/0705    
	Segment *s; 
1990/0227    
	Page *np, *op; 
	ulong usp, upa, pid; 
	Chan *c; 
	Orig *o; 
1990/0614    
	KMap *k; 
1990/0227    
	int n, on, i; 
	int lastvar;	/* used to compute stack address */ 
                 
	/* 
	 * Kernel stack 
	 */ 
	p = newproc(); 
1991/0705    
 
	/* Page va of upage used as check in mapstack */ 
1990/0227    
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); 
1990/0614    
	k = kmap(p->upage); 
	upa = VA(k); 
1991/0619/sys/src/9/port/sysproc.c:49,1161991/0705/sys/src/9/port/sysproc.c:49,71
1990/0227    
	((User *)upa)->p = p; 
1990/0614    
	kunmap(k); 
1990/0227    
 
1991/0705    
	/* Make a new set of memory segments */ 
	for(i = 0; i < NSEG; i++) 
		if(u->p->seg[i]) 
			p->seg[i] = dupseg(u->p->seg[i]); 
 
1990/0227    
	/* 
	 * User stack 
	 */ 
	p->seg[SSEG] = u->p->seg[SSEG]; 
	s = &p->seg[SSEG]; 
	s->proc = p; 
	on = (s->maxva-s->minva)>>PGSHIFT; 
1990/0614    
	usp = ((Ureg*)UREGADDR)->usp; 
1990/0227    
	if(usp >= USTKTOP) 
		panic("fork bad usp %lux", usp); 
	if(usp < u->p->seg[SSEG].minva) 
		s->minva = u->p->seg[SSEG].minva; 
	else 
		s->minva = usp & ~(BY2PG-1); 
	usp = s->minva & (BY2PG-1);	/* just low bits */ 
	s->maxva = USTKTOP; 
	n = (s->maxva-s->minva)>>PGSHIFT; 
1991/0607    
	s->o = neworig(s->minva, n, OWRPERM|OISMEM, 0); 
1990/0227    
	lock(s->o); 
	/* 
	 * Only part of last stack page 
	 */ 
	for(i=0; i<n; i++){ 
		op = u->p->seg[SSEG].o->pte[i+(on-n)].page; 
		if(op){ 
			np = newpage(1, s->o, op->va); 
1990/0614    
			k = kmap(np); 
1990/0227    
			p->seg[SSEG].o->pte[i].page = np; 
			if(i == 0){	/* only part of last stack page */ 
1990/0614    
				memset((void*)VA(k), 0, usp); 
1991/0318    
				memmove((void*)(VA(k)+usp), 
1990/0614    
					(void*)(op->va+usp), BY2PG-usp); 
1990/0227    
			}else		/* all of higher pages */ 
1991/0318    
				memmove((void*)VA(k), (void*)op->va, BY2PG); 
1990/0614    
			kunmap(k); 
1990/0227    
		} 
	} 
	unlock(s->o); 
	/* 
	 * Duplicate segments 
	 */ 
	for(s=&u->p->seg[0], n=0; n<NSEG; n++, s++){ 
		if(n == SSEG)		/* already done */ 
			continue; 
		if(s->o == 0) 
			continue; 
		p->seg[n] = *s; 
		p->seg[n].proc = p; 
		o = s->o; 
		lock(o); 
		o->nproc++; 
		if(s->mod) 
			forkmod(s, &p->seg[n], p); 
		unlock(o); 
	} 
	/* 
	 * Refs 
	 */ 
	incref(u->dot); 
	for(n=0; n<=u->maxfd; n++) 
		if(c = u->fd[n])	/* assign = */ 
			incref(c); 
1991/0705    
	incref(u->dot);				/* File descriptors etc. */ 
	p->fgrp = dupfgrp(u->p->fgrp); 
 
	p->pgrp = u->p->pgrp;			/* Process groups */ 
	incref(p->pgrp); 
 
	p->egrp = u->p->egrp;			/* Environment group */ 
	incref(p->egrp); 
 
1990/0227    
	/* 
	 * Sched 
	 */ 
1991/0619/sys/src/9/port/sysproc.c:122,1321991/0705/sys/src/9/port/sysproc.c:77,87
1990/0227    
		spllo(); 
		return 0; 
	} 
1991/0705    
 
1990/0227    
	p->parent = u->p; 
	p->parentpid = u->p->pid; 
	p->pgrp = u->p->pgrp; 
1991/0705    
 
1991/0118    
	p->fpstate = u->p->fpstate; 
1990/0227    
	incref(p->pgrp); 
1990/0324    
	u->p->nchild++; 
1990/0227    
	pid = p->pid; 
	memset(p->time, 0, sizeof(p->time)); 
1991/0619/sys/src/9/port/sysproc.c:147,1571991/0705/sys/src/9/port/sysproc.c:102,111
1990/0227    
sysexec(ulong *arg) 
{ 
	Proc *p; 
	Seg *s; 
1991/0705    
	Segment *s, *ts; 
1990/0227    
	ulong l, t, d, b, v; 
	int i; 
1990/08141    
	Chan *tc, *c; 
1990/0227    
	Orig *o; 
	char **argv, **argp; 
	char *a, *charp, *file; 
	char *progarg[sizeof(Exec)/2+1], elem[NAMELEN]; 
1991/0619/sys/src/9/port/sysproc.c:160,1651991/0705/sys/src/9/port/sysproc.c:114,121
1990/0227    
	int indir; 
	Exec exec; 
	char line[sizeof(Exec)]; 
1991/0705    
	Fgrp *f; 
	Image *img; 
1990/0227    
 
	p = u->p; 
	validaddr(arg[0], 1, 0); 
1991/0619/sys/src/9/port/sysproc.c:209,2141991/0705/sys/src/9/port/sysproc.c:165,171
1990/0227    
	goto Header; 
 
    Binary: 
1991/0705    
	poperror(); 
1990/0227    
	t = (UTZERO+sizeof(Exec)+exec.text+(BY2PG-1)) & ~(BY2PG-1); 
1990/1212    
	d = (t + exec.data + (BY2PG-1)) & ~(BY2PG-1); 
1990/1211    
	bssend = t + exec.data + exec.bss; 
1991/0619/sys/src/9/port/sysproc.c:237,2431991/0705/sys/src/9/port/sysproc.c:194,200
1990/0227    
		if(((ulong)argp&(BY2PG-1)) < BY2WD) 
			validaddr((ulong)argp, BY2WD, 0); 
		validaddr((ulong)a, 1, 0); 
1991/0619    
		nbytes += (vmemchr(a, 0, ~0) - a) + 1; 
1991/0705    
		nbytes += (vmemchr(a, 0, 0xFFFFFFFF) - a) + 1; 
1990/1226    
		nargs++; 
1990/0227    
	} 
	ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1)); 
1991/0619/sys/src/9/port/sysproc.c:248,2581991/0705/sys/src/9/port/sysproc.c:205,212
1991/0523    
	if(spage > TSTKSIZ) 
1991/0522    
		errors("not enough argument stack space"); 
 
1990/0227    
	s = &p->seg[ESEG]; 
	s->proc = p; 
1991/0607    
	s->o = neworig(TSTKTOP-(spage<<PGSHIFT), spage, OWRPERM|OISMEM, 0); 
1990/0227    
	s->minva = s->o->va; 
	s->maxva = TSTKTOP; 
1991/0705    
	  
	p->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG); 
1990/0227    
 
	/* 
	 * Args: pass 2: assemble; the pages will be faulted in 
1991/0619/sys/src/9/port/sysproc.c:263,2701991/0705/sys/src/9/port/sysproc.c:217,225
1990/0227    
		argp = progarg; 
	else 
		argp = (char**)arg[1]; 
1991/0705    
 
1990/0227    
	for(i=0; i<nargs; i++){ 
		if(indir && *argp==0){ 
1991/0705    
		if(indir && *argp==0) { 
1990/0227    
			indir = 0; 
			argp = (char**)arg[1]; 
		} 
1991/0619/sys/src/9/port/sysproc.c:276,3621991/0705/sys/src/9/port/sysproc.c:231,295
1990/0227    
 
1991/0318    
	memmove(p->text, elem, NAMELEN); 
1990/0227    
 
1991/0705    
	if(waserror()) 
		pexit("fatal exec error", 0); 
 
1990/0227    
	/* 
	 * Committed.  Free old memory 
1991/0705    
	 * Committed.  Free old memory. Special segments are maintained accross exec 
1990/0227    
	 */ 
	freesegs(ESEG); 
1991/0705    
	putseg(p->seg[TSEG]); 
	p->seg[TSEG] = 0;	/* prevent a second free if we have an error */ 
	putseg(p->seg[DSEG]); 
	p->seg[DSEG] = 0; 
	putseg(p->seg[BSEG]); 
	p->seg[BSEG] = 0; 
	putseg(p->seg[SSEG]); 
	p->seg[SSEG] = 0; 
1990/08141    
 
	/* 
	 * Close on exec 
	 */ 
	for(i=0; i<=u->maxfd; i++) 
		if((c=u->fd[i]) && c->flag&CCEXEC){ 
			close(c); 
			fdclose(i); 
		} 
1991/0705    
	f = u->p->fgrp; 
	for(i=0; i<=f->maxfd; i++) 
		fdclose(i, CCEXEC); 
1990/0227    
 
	/* 
	 * Text.  Shared. 
	 */ 
	s = &p->seg[TSEG]; 
	s->proc = p; 
1991/0607    
	o = lookorig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED|OISMEM, tc); 
1990/0227    
	if(o == 0){ 
1991/0607    
		o = neworig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED|OISMEM, tc); 
1990/0227    
		o->minca = 0; 
		o->maxca = sizeof(Exec)+exec.text; 
	} 
	s->o = o; 
	s->minva = UTZERO; 
	s->maxva = t; 
	s->mod = 0; 
1991/0705    
	/* Text.  Shared. Attaches to cache image if possible */ 
	img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT); 
	ts = img->s; 
	p->seg[TSEG] = ts; 
	ts->fstart = 0; 
	ts->flen = sizeof(Exec)+exec.text; 
1990/0227    
 
	/* 
	 * Data.  Shared. 
	 */ 
	s = &p->seg[DSEG]; 
	s->proc = p; 
1991/0607    
	o = lookorig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED|OISMEM, tc); 
1990/0227    
	if(o == 0){ 
1991/0607    
		o = neworig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED|OISMEM, tc); 
1990/0227    
		o->minca = p->seg[TSEG].o->maxca; 
1990/1212    
		o->maxca = o->minca + exec.data; 
1990/0227    
	} 
	s->o = o; 
	s->minva = t; 
	s->maxva = d; 
	s->mod = 0; 
1991/0705    
	/* Data. Shared. */ 
	s = newseg(SG_DATA, t, (d-t)>>PGSHIFT); 
	p->seg[DSEG] = s; 
1990/0227    
 
	/* 
1990/1212    
	 * BSS.  Created afresh. 
1990/0227    
	 */ 
	s = &p->seg[BSEG]; 
	s->proc = p; 
1991/0607    
	o = neworig(d, (b-d)>>PGSHIFT, OWRPERM|OISMEM, 0); 
1990/1212    
	o->minca = 0; 
	o->maxca = 0; 
1990/0227    
	s->o = o; 
	s->minva = d; 
	s->maxva = b; 
	s->mod = 0; 
1991/0705    
	/* Attached by hand */ 
	incref(img); 
	s->image = img; 
	s->fstart = ts->fstart+ts->flen; 
	s->flen = exec.data; 
1990/0227    
 
1991/0614    
	poperror(); 
1990/0227    
	close(tc); 
 
1991/0606    
	p->seg[BSEG].endseg = bssend; 
1991/0705    
	/* BSS. Zero fill on demand */ 
	p->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT); 
1990/1211    
 
1991/0705    
	close(tc); 
 
1990/0227    
	/* 
	 * Move the stack 
	 */ 
	s = &p->seg[SSEG]; 
	*s = p->seg[ESEG]; 
	p->seg[ESEG].o = 0; 
	o = s->o; 
	o->va += (USTKTOP-TSTKTOP); 
	s->minva = o->va; 
	s->maxva = USTKTOP; 
	lock(o); 
	for(i=0; i<o->npte; i++) 
		o->pte[i].page->va += (USTKTOP-TSTKTOP); 
	unlock(o); 
1991/0705    
	s = p->seg[ESEG]; 
	p->seg[SSEG] = s; 
	s->base = USTKTOP-USTKSIZE; 
	s->top = USTKTOP; 
	relocateseg(s, TSTKTOP-USTKTOP); 
	p->seg[ESEG] = 0; 
1990/0227    
 
1991/0705    
	poperror(); 
 
1991/0529    
	/* 
	 *  at this point, the mmu contains info about the old address 
1991/0705    
	 *  At this point, the mmu contains info about the old address 
1991/0529    
	 *  space and needs to be flushed 
	 */ 
1990/0227    
	flushmmu(); 
1991/0619/sys/src/9/port/sysproc.c:437,4421991/0705/sys/src/9/port/sysproc.c:370,376
1990/0227    
			vmemchr(status, 0, ERRLEN); 
		} 
1991/0614    
		poperror(); 
1991/0705    
 
1990/0227    
	} 
	pexit(status, 1); 
} 
1991/0619/sys/src/9/port/sysproc.c:473,4821991/0705/sys/src/9/port/sysproc.c:407,419
1990/0227    
{ 
1991/0514    
	int mask; 
1990/0227    
	Pgrp *pg; 
1991/0705    
	Egrp *eg; 
1990/0227    
 
	pg = newpgrp(); 
1991/0705    
	eg = newegrp(); 
1990/0227    
	if(waserror()){ 
		closepgrp(pg); 
1991/0705    
		closeegrp(eg); 
1990/0227    
		nexterror(); 
	} 
1991/0514    
 
1991/0619/sys/src/9/port/sysproc.c:490,4961991/0705/sys/src/9/port/sysproc.c:427,433
1990/0227    
		pgrpcpy(pg, u->p->pgrp); 
1991/0514    
 
	if(mask & FPenv) 
		envcpy(pg, u->p->pgrp); 
1991/0705    
		envcpy(eg, u->p->egrp); 
1991/0514    
 
	if((mask & FPnote) == 0) { 
		u->nnote = 0; 
1991/0619/sys/src/9/port/sysproc.c:500,5061991/0705/sys/src/9/port/sysproc.c:437,445
1991/0514    
 
1991/0614    
	poperror(); 
1990/0227    
	closepgrp(u->p->pgrp); 
1991/0705    
	closeegrp(u->p->egrp); 
1990/0227    
	u->p->pgrp = pg; 
1991/0705    
	u->p->egrp = eg; 
1990/0227    
	return pg->pgrpid; 
} 
 
1991/0619/sys/src/9/port/sysproc.c:521,5371991/0705/sys/src/9/port/sysproc.c:460,551
1990/0227    
	return 0; 
} 
 
/* 
 * Temporary; should be replaced by a generalized segment control operator 
 */ 
long 
sysbrk_(ulong *arg) 
1991/0705    
syssegbrk(ulong *arg) 
1990/0227    
{ 
1991/0606    
	return ibrk(arg[0], BSEG); 
1991/0705    
	Segment *s; 
	int i; 
 
	for(i = 0; i < NSEG; i++) 
		if(s = u->p->seg[i]) { 
			if(arg[0] >= s->base && arg[0] < s->top) { 
				switch(s->type&SG_TYPE) { 
				case SG_TEXT: 
				case SG_DATA: 
					errors("bad segment type"); 
				default: 
					return ibrk(arg[1], i); 
				} 
			} 
		} 
 
	errors("not in address space"); 
1990/0227    
} 
1991/0606    
 
1991/0605    
long 
1991/0606    
syslkbrk_(ulong *arg) 
1991/0705    
syssegattach(ulong *arg) 
1991/0605    
{ 
1991/0606    
	return ibrk(arg[0], LSEG); 
1991/0705    
	return segattach(u->p, arg[0], (char*)arg[1], arg[2], arg[3]); 
} 
 
long 
syssegdetach(ulong *arg) 
{ 
	int i; 
	Segment *s; 
 
	for(i = 0; i < NSEG; i++) 
		if(s = u->p->seg[i]) { 
			qlock(&s->lk); 
			if((arg[0] >= s->base && arg[0] < s->top) ||  
			   (s->top == s->base && arg[0] == s->base)) 
				goto found; 
			qunlock(&s->lk); 
		} 
 
	errors("not in address space"); 
 
found: 
	if((ulong)arg >= s->base && (ulong)arg < s->top) { 
		qunlock(&s->lk); 
		errors("illegal address"); 
	} 
	u->p->seg[i] = 0; 
	qunlock(&s->lk); 
	putseg(s); 
 
	/* Ensure we flush any entries from the lost segment */ 
	flushmmu(); 
	return 0; 
} 
 
long 
syssegfree(ulong *arg) 
{ 
	Segment *s; 
	ulong from, len; 
 
	s = seg(u->p, arg[0], 1); 
	if(s == 0) 
		errors("not in address space"); 
 
	from = PGROUND(arg[1]); 
	len = arg[2]; 
 
	if(from+len > s->top) { 
		qunlock(&s->lk); 
		errors("segment too short"); 
	} 
 
	mfreeseg(s, from, len); 
	qunlock(&s->lk); 
 
	return 0; 
} 
 
/* For binary compatability */ 
long 
sysbrk_(ulong *arg) 
{ 
	return ibrk(arg[0], BSEG); 
1991/0605    
} 


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