Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/sysproc.c

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


## diffname port/sysproc.c 1990/0227
## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/sysproc.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"ureg.h"
#include	"errno.h"

#include	<v.out.h>

int	shargs(char*, int, char**);

long
sysr1(ulong *arg)
{
	print("[%d] r1 = %d\n", u->p->pid, arg[0]);
	return 0;
}

long
sysfork(ulong *arg)
{
	Proc *p;
	Seg *s;
	Page *np, *op;
	ulong usp, upa, pid;
	Chan *c;
	Orig *o;
	int n, on, i;
	int lastvar;	/* used to compute stack address */

	/*
	 * Kernel stack
	 */
	p = newproc();
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
	upa = p->upage->pa|KZERO;
	/*
	 * Save time: only copy u-> data and useful stack
	 */
	memcpy((void*)upa, u, sizeof(User));
	n = USERADDR+BY2PG - (ulong)&lastvar;
	n = (n+32) & ~(BY2WD-1);	/* be safe & word align */
	memcpy((void*)(upa+BY2PG-n), (void*)((u->p->upage->pa|KZERO)+BY2PG-n), n);
	((User *)upa)->p = p;

	/*
	 * User stack
	 */
	p->seg[SSEG] = u->p->seg[SSEG];
	s = &p->seg[SSEG];
	s->proc = p;
	on = (s->maxva-s->minva)>>PGSHIFT;
	usp = ((Ureg*)UREGADDR)->sp;
	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;
	s->o = neworig(s->minva, n, OWRPERM, 0);
	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);
			p->seg[SSEG].o->pte[i].page = np;
			if(i == 0){	/* only part of last stack page */
				memset((void*)(np->pa|KZERO), 0, usp);
				memcpy((void*)((np->pa+usp)|KZERO),
					(void*)((op->pa+usp)|KZERO), BY2PG-usp);
			}else		/* all of higher pages */
				memcpy((void*)(np->pa|KZERO), (void*)(op->pa|KZERO), BY2PG);
		}
	}
	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);
	/*
	 * Sched
	 */
	if(setlabel(&p->sched)){
		u->p = p;
		p->state = Running;
		p->mach = m;
		m->proc = p;
		spllo();
		return 0;
	}
	p->parent = u->p;
	p->parentpid = u->p->pid;
	p->pgrp = u->p->pgrp;
	incref(p->pgrp);
	u->p->nchild++;
	pid = p->pid;
	memset(p->time, 0, sizeof(p->time));
	p->time[TReal] = MACHP(0)->ticks;
	memcpy(p->text, u->p->text, NAMELEN);
	ready(p);
	flushmmu();
	return pid;
}

long
sysexec(ulong *arg)
{
	Proc *p;
	Seg *s;
	ulong l, t, d, b, v;
	int i;
	Chan *tc;
	Orig *o;
	char **argv, **argp;
	char *a, *charp, *file;
	char *progarg[sizeof(Exec)/2+1], elem[NAMELEN];
	ulong ssize, spage, nargs, nbytes, n;
	ulong *sp;
	int indir;
	Exec exec;
	char line[sizeof(Exec)];

	p = u->p;
	validaddr(arg[0], 1, 0);
	file = (char*)arg[0];
	indir = 0;
    Header:
	tc = namec(file, Aopen, OEXEC, 0);
	if(waserror()){
		close(tc);
		nexterror();
	}
	if(!indir)
		strcpy(elem, u->elem);
	n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec));
	if(n < 2)
    Err:
		error(0, Ebadexec);
	if(n==sizeof(Exec) && exec.magic==V_MAGIC){
		if((exec.text&KZERO)
		|| (ulong)exec.entry < UTZERO+sizeof(Exec)
		|| (ulong)exec.entry >= UTZERO+sizeof(Exec)+exec.text)
			goto Err;
		goto Binary;
	}

	/*
	 * Process #! /bin/sh args ...
	 */
	memcpy(line, &exec, sizeof(Exec));
	if(indir || line[0]!='#' || line[1]!='!')
		goto Err;
	n = shargs(line, n, progarg);
	if(n == 0)
		goto Err;
	indir = 1;
	/*
	 * First arg becomes complete file name
	 */
	progarg[n++] = file;
	progarg[n] = 0;
	validaddr(arg[1], BY2WD, 1);
	arg[1] += BY2WD;
	file = progarg[0];
	progarg[0] = elem;
	close(tc);
	poperror();
	goto Header;

    Binary:
	t = (UTZERO+sizeof(Exec)+exec.text+(BY2PG-1)) & ~(BY2PG-1);
	/*
	 * Last partial page of data goes into BSS.
	 */
	d = (t + exec.data) & ~(BY2PG-1);
	b = (t + exec.data + exec.bss + (BY2PG-1)) & ~(BY2PG-1);
	if((t|d|b) & KZERO)
		error(0, Ebadexec);

	/*
	 * Args: pass 1: count
	 */
	nbytes = 0;
	nargs = 0;
	if(indir){
		argp = progarg;
		while(*argp){
			a = *argp++;
			nbytes += strlen(a) + 1;
			nargs++;
		}
	}
	evenaddr(arg[1]);
	argp = (char**)arg[1];
	validaddr((ulong)argp, BY2WD, 0);
	while(*argp){
		a = *argp++;
		if(((ulong)argp&(BY2PG-1)) < BY2WD)
			validaddr((ulong)argp, BY2WD, 0);
		validaddr((ulong)a, 1, 0);
		nbytes += (vmemchr(a, 0, 0xFFFFFFFF) - a) + 1;
			nargs++;
	}
	ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1));
	spage = (ssize+(BY2PG-1)) >> PGSHIFT;

	/*
	 * Build the stack segment, putting it in kernel virtual for the moment
	 */
	s = &p->seg[ESEG];
	s->proc = p;
	s->o = neworig(TSTKTOP-(spage<<PGSHIFT), spage, OWRPERM, 0);
	s->minva = s->o->va;
	s->maxva = TSTKTOP;

	/*
	 * Args: pass 2: assemble; the pages will be faulted in
	 */
	argv = (char**)(TSTKTOP - ssize);
	charp = (char*)(TSTKTOP - nbytes);
	if(indir)
		argp = progarg;
	else
		argp = (char**)arg[1];
	for(i=0; i<nargs; i++){
		if(indir && *argp==0){
			indir = 0;
			argp = (char**)arg[1];
		}
		*argv++ = charp + (USTKTOP-TSTKTOP);
		n = strlen(*argp) + 1;
		memcpy(charp, *argp++, n);
		charp += n;
	}

	memcpy(p->text, elem, NAMELEN);

	/*
	 * Committed.  Free old memory
	 */
	freesegs(ESEG);

	/*
	 * Text.  Shared.
	 */
	s = &p->seg[TSEG];
	s->proc = p;
	o = lookorig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED, tc);
	if(o == 0){
		o = neworig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED, tc);
		o->minca = 0;
		o->maxca = sizeof(Exec)+exec.text;
	}
	s->o = o;
	s->minva = UTZERO;
	s->maxva = t;
	s->mod = 0;

	/*
	 * Data.  Shared.
	 */
	s = &p->seg[DSEG];
	s->proc = p;
	o = lookorig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED, tc);
	if(o == 0){
		o = neworig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED, tc);
		o->minca = p->seg[TSEG].o->maxca;
		o->maxca = o->minca + (exec.data & ~(BY2PG-1));
	}
	s->o = o;
	s->minva = t;
	s->maxva = d;
	s->mod = 0;

	/*
	 * BSS.  Created afresh, starting with last page of data.
	 * BUG: should pick up the last page of data, which should be cached in the
	 * data segment.
	 */
	s = &p->seg[BSEG];
	s->proc = p;
	o = neworig(d, (b-d)>>PGSHIFT, OWRPERM, tc);
	o->minca = p->seg[DSEG].o->maxca;
	o->maxca = o->minca + (exec.data & (BY2PG-1));
	s->o = o;
	s->minva = d;
	s->maxva = b;
	s->mod = 0;

	close(tc);

	/*
	 * 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);

	flushmmu();
	((Ureg*)UREGADDR)->pc = exec.entry - 4;
	sp = (ulong*)(USTKTOP - ssize);
	*--sp = nargs;
	((Ureg*)UREGADDR)->sp = (ulong)sp;
	lock(&p->debug);
	u->nnote = 0;
	u->notify = 0;
	u->notified = 0;
	unlock(&p->debug);
	return 0;
}

int
shargs(char *s, int n, char **ap)
{
	int i;

	s += 2, n -= 2;		/* skip #! */
	for(i=0; s[i]!='\n'; i++)
		if(i == n-1)
			return 0;
	s[i] = 0;
	*ap = 0;
	i = 0;
	for(;;){
		while(*s==' ' || *s=='\t')
			s++;
		if(*s == 0)
			break;
		i++;
		*ap++ = s;
		*ap = 0;
		while(*s && *s!=' ' && *s!='\t')
			s++;
		if(*s == 0)
			break;
		else
			*s++ = 0;
	}
	return i;
}

int
return0(void *a)
{
	return 0;
}

long
syssleep(ulong *arg)
{
	int ms;

	tsleep(&u->p->sleep, return0, 0, arg[0]);
	return 0;
}


long
sysexits(ulong *arg)
{
	char *status;

	status = (char*)arg[0];
	if(status){
		if(waserror())
			status = "invalid exit string";
		else{
			validaddr((ulong)status, 1, 0);
			vmemchr(status, 0, ERRLEN);
		}
	}
	pexit(status, 1);
}

long
syswait(ulong *arg)
{
	if(arg[0]){
		validaddr(arg[0], sizeof(Waitmsg), 1);
		evenaddr(arg[0]);
	}
	return pwait((Waitmsg*)arg[0]);
}

long
syslasterr(ulong *arg)
{
	Error *e;

	validaddr(arg[0], sizeof u->error, 1);
	evenaddr(arg[0]);
	e = (Error *)arg[0];
	memcpy(e, &u->error, sizeof u->error);
	memset(&u->error, 0, sizeof u->error);
	e->type = devchar[e->type];
	return 0;
}

long
syserrstr(ulong *arg)
{
	Error *e, err;
	char buf[ERRLEN];

	validaddr(arg[1], ERRLEN, 1);
	e = &err;
	if(arg[0]){
		validaddr(arg[0], sizeof u->error, 0);
		memcpy(e, (Error*)arg[0], sizeof(Error));
		e->type = devno(e->type, 1);
		if(e->type == -1){
			e->type = 0;
			e->code = Egreg+1;	/* -> "no such error" */
		}
	}else{
		memcpy(e, &u->error, sizeof(Error));
		memset(&u->error, 0, sizeof(Error));
	}
	(*devtab[e->type].errstr)(e, buf);
	memcpy((char*)arg[1], buf, sizeof buf);
	return 0;
}

long
sysforkpgrp(ulong *arg)
{
	Pgrp *pg;

	pg = newpgrp();
	if(waserror()){
		closepgrp(pg);
		nexterror();
	}
	if(arg[0] == 0)
		pgrpcpy(pg, u->p->pgrp);
	closepgrp(u->p->pgrp);
	u->p->pgrp = pg;
	return pg->pgrpid;
}

long
sysnotify(ulong *arg)
{
	validaddr(arg[0], sizeof(ulong), 0);
	u->notify = (int(*)(void*, char*))(arg[0]);
	return 0;
}

long
sysnoted(ulong *arg)
{
	if(u->notified == 0)
		error(0, Egreg);
	return 0;
}

/*
 * Temporary; should be replaced by a generalized segment control operator
 */
long
sysbrk_(ulong *arg)
{
	if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0)
		error(0, Esegaddr);
	return 0;
}
.
## diffname port/sysproc.c 1990/03081
## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/sysproc.c /n/bootesdump/1990/03081/sys/src/9/mips/sysproc.c
117a
	p->pop = u->p;
.
107a
	 * Committed.  Link into hierarchy
	 */
	lock(&p->kidlock);
	lock(&u->p->kidlock);
	if(u->p->kid == 0){
		p->sib = p;
		u->p->kid = p;
	}else{
		p->sib = u->p->kid->sib;
		u->p->kid->sib = p;
	}
	unlock(&u->p->kidlock);
	unlock(&p->kidlock);
	/*
.
## diffname port/sysproc.c 1990/0322
## diff -e /n/bootesdump/1990/03081/sys/src/9/mips/sysproc.c /n/bootesdump/1990/0322/sys/src/9/mips/sysproc.c
137d
## diffname port/sysproc.c 1990/0324
## diff -e /n/bootesdump/1990/0322/sys/src/9/mips/sysproc.c /n/bootesdump/1990/0324/sys/src/9/mips/sysproc.c
136a
	u->p->nchild++;
.
## diffname port/sysproc.c 1990/0330
## diff -e /n/bootesdump/1990/0324/sys/src/9/mips/sysproc.c /n/bootesdump/1990/0330/sys/src/9/mips/sysproc.c
9c
#include	<a.out.h>
.
## diffname port/sysproc.c 1990/0614
## diff -e /n/bootesdump/1990/0330/sys/src/9/mips/sysproc.c /n/bootesdump/1990/0614/sys/src/9/mips/sysproc.c
353c
	((Ureg*)UREGADDR)->usp = (ulong)sp;
.
79c
				memcpy((void*)VA(k), (void*)op->va, BY2PG);
			kunmap(k);
.
75,77c
				memset((void*)VA(k), 0, usp);
				memcpy((void*)(VA(k)+usp),
					(void*)(op->va+usp), BY2PG-usp);
.
72a
			k = kmap(np);
.
54c
	usp = ((Ureg*)UREGADDR)->usp;
.
45a
	kunmap(k);
.
44c
	memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
.
37c
	k = kmap(p->upage);
	upa = VA(k);

.
28a
	KMap *k;
.
## diffname port/sysproc.c 1990/0619
## diff -e /n/bootesdump/1990/0614/sys/src/9/mips/sysproc.c /n/bootesdump/1990/0619/sys/src/9/mips/sysproc.c
407,408d
## diffname port/sysproc.c 1990/08141
## diff -e /n/bootesdump/1990/0619/sys/src/9/mips/sysproc.c /n/bootesdump/1990/08141/sys/src/9/mips/sysproc.c
289a

	/*
	 * Close on exec
	 */
	for(i=0; i<=u->maxfd; i++)
		if((c=u->fd[i]) && c->flag&CCEXEC){
			close(c);
			fdclose(i);
		}
.
160c
	Chan *tc, *c;
.
## diffname port/sysproc.c 1990/1009
## diff -e /n/bootesdump/1990/08141/sys/src/9/mips/sysproc.c /n/bootesdump/1990/1009/sys/src/9/mips/sysproc.c
498a
	else
		memcpy(pg->user, u->p->pgrp->user, NAMELEN);
.
## diffname port/sysproc.c 1990/11211
## diff -e /n/bootesdump/1990/1009/sys/src/9/mips/sysproc.c /n/bootesdump/1990/11211/sys/src/9/mips/sysproc.c
529c
		error(Esegaddr);
.
518c
		error(Egreg);
.
468,483c
	validaddr(arg[0], ERRLEN, 1);
	memcpy((char*)arg[0], u->error, ERRLEN);
.
465d
451,459c
	pprint("deprecated system call");
	pexit("Suicide", 0);
.
449c
sysdeath(ulong *arg)
.
226c
		error(Ebadexec);
.
186c
		error(Ebadexec);
.
## diffname port/sysproc.c 1990/1123
## diff -e /n/bootesdump/1990/11211/sys/src/9/mips/sysproc.c /n/bootesdump/1990/1123/sys/src/9/mips/sysproc.c
16c
	print("[%s %s %d] r1 = %d\n", u->p->pgrp->user, u->p->text, u->p->pid, arg[0]);
.
## diffname port/sysproc.c 1990/1124
## diff -e /n/bootesdump/1990/1123/sys/src/9/mips/sysproc.c /n/bootesdump/1990/1124/sys/src/9/mips/sysproc.c
138d
114,127d
## diffname port/sysproc.c 1990/1211
## diff -e /n/bootesdump/1990/1211/sys/src/9/mips/sysproc.c /n/bootesdump/1990/1211/sys/src/9/port/sysproc.c
492a
	}
#endif WHYROB
	if(addr <= ((u->p->bssend+(BY2PG-1))&~(BY2PG-1)))	/* still in DSEG */
		goto Return;
	if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0){
		pprint("bad segaddr in brk\n");
		pexit("Suicide", 0);
		error(Esegaddr);
	}
    Return:
	u->p->bssend = addr;
.
491c
	ulong addr;
	Seg *s;

	addr = arg[0];
#ifdef WHYROB
	if(addr < u->p->bssend){
		pprint("addr below bss\n");
		pexit("Suicide", 0);
.
357a
	setup(p);
.
350c
 	clearmmucache();
	((Ureg*)UREGADDR)->pc = exec.entry + ENTRYOFFSET;
.
333a
	p->bssend = bssend;

.
209c
	bssend = t + exec.data + exec.bss;
	b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
.
172c
	if(n==sizeof(Exec) && exec.magic==AOUT_MAGIC){
.
150c
	ulong ssize, spage, nargs, nbytes, n, bssend;
.
134a
	clearmmucache();
.
116a
		clearmmucache();
.
43a
	clearmmucache();
.
## diffname port/sysproc.c 1990/1212
## diff -e /n/bootesdump/1990/1211/sys/src/9/port/sysproc.c /n/bootesdump/1990/1212/sys/src/9/port/sysproc.c
365c
	procsetup(p);
.
356c
	clearmmucache();
.
328,330c
	o = neworig(d, (b-d)>>PGSHIFT, OWRPERM, 0);
	o->minca = 0;
	o->maxca = 0;
.
322,324c
	 * BSS.  Created afresh.
.
314c
		o->maxca = o->minca + exec.data;
.
208,211c
	d = (t + exec.data + (BY2PG-1)) & ~(BY2PG-1);
.
## diffname port/sysproc.c 1990/1226
## diff -e /n/bootesdump/1990/1212/sys/src/9/port/sysproc.c /n/bootesdump/1990/1226/sys/src/9/port/sysproc.c
352c
	execpc(exec.entry);
.
236c
		nargs++;
.
## diffname port/sysproc.c 1990/1227
## diff -e /n/bootesdump/1990/1226/sys/src/9/port/sysproc.c /n/bootesdump/1990/1227/sys/src/9/port/sysproc.c
504d
498d
128a
	p->bssend = u->p->bssend;
.
## diffname port/sysproc.c 1991/0118
## diff -e /n/bootesdump/1990/1227/sys/src/9/port/sysproc.c /n/bootesdump/1991/0118/sys/src/9/port/sysproc.c
129a
	p->fpstate = u->p->fpstate;
.
## diffname port/sysproc.c 1991/0318
## diff -e /n/bootesdump/1991/0118/sys/src/9/port/sysproc.c /n/bootesdump/1991/0318/sys/src/9/port/sysproc.c
468c
		memmove(pg->user, u->p->pgrp->user, NAMELEN);
.
451c
	memmove((char*)arg[0], u->error, ERRLEN);
.
272c
	memmove(p->text, elem, NAMELEN);
.
268c
		memmove(charp, *argp++, n);
.
188c
	memmove(line, &exec, sizeof(Exec));
.
136c
	memmove(p->text, u->p->text, NAMELEN);
.
85c
				memmove((void*)VA(k), (void*)op->va, BY2PG);
.
82c
				memmove((void*)(VA(k)+usp),
.
48c
	memmove((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
.
45c
	memmove((void*)upa, u, sizeof(User));
.
## diffname port/sysproc.c 1991/0326
## diff -e /n/bootesdump/1991/0318/sys/src/9/port/sysproc.c /n/bootesdump/1991/0326/sys/src/9/port/sysproc.c
477c
	if(arg[0] != 0)
		validaddr(arg[0], sizeof(ulong), 0);
.
## diffname port/sysproc.c 1991/0411
## diff -e /n/bootesdump/1991/0326/sys/src/9/port/sysproc.c /n/bootesdump/1991/0411/sys/src/9/port/sysproc.c
173c
	n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec), 0);
.
## diffname port/sysproc.c 1991/0430
## diff -e /n/bootesdump/1991/0411/sys/src/9/port/sysproc.c /n/bootesdump/1991/0430/sys/src/9/port/sysproc.c
139a
	ready(p);
.
137d
## diffname port/sysproc.c 1991/0513
## diff -e /n/bootesdump/1991/0430/sys/src/9/port/sysproc.c /n/bootesdump/1991/0513/sys/src/9/port/sysproc.c
409a
long
sysalarm(ulong *arg)
{
	return procalarm(arg[0]);		
}
.
## diffname port/sysproc.c 1991/0514
## diff -e /n/bootesdump/1991/0513/sys/src/9/port/sysproc.c /n/bootesdump/1991/0514/sys/src/9/port/sysproc.c
472,473c

	if(mask & FPenv)
		envcpy(pg, u->p->pgrp);

	if((mask & FPnote) == 0) {
		u->nnote = 0;
		u->notified = 0;
		memset(u->note, 0, sizeof(u->note));
	}

.
470c

	mask = arg[0];
	if(mask == FPall)
		mask = FPnote|FPenv|FPnamespc;

	memmove(pg->user, u->p->pgrp->user, NAMELEN);

	if(mask & FPnamespc)
.
462a
	int mask;
.
## diffname port/sysproc.c 1991/0522
## diff -e /n/bootesdump/1991/0514/sys/src/9/port/sysproc.c /n/bootesdump/1991/0522/sys/src/9/port/sysproc.c
248c
	s->o = neworig(sbase, spage, OWRPERM, 0);
.
245a
	if(sbase <= USERADDR)
		errors("not enough argument stack space");

.
242c
	sbase = TSTKTOP-(spage<<PGSHIFT);
.
155c
	ulong sbase, ssize, spage, nargs, nbytes, n, bssend;
.
## diffname port/sysproc.c 1991/0523
## diff -e /n/bootesdump/1991/0522/sys/src/9/port/sysproc.c /n/bootesdump/1991/0523/sys/src/9/port/sysproc.c
251c
	s->o = neworig(TSTKTOP-(spage<<PGSHIFT), spage, OWRPERM, 0);
.
246c
	if(spage > TSTKSIZ)
.
242d
155c
	ulong ssize, spage, nargs, nbytes, n, bssend;
.
## diffname port/sysproc.c 1991/0529
## diff -e /n/bootesdump/1991/0523/sys/src/9/port/sysproc.c /n/bootesdump/1991/0529/sys/src/9/port/sysproc.c
353a
	/*
	 *  at this point, the mmu contains info about the old address
	 *  space and needs to be flushed
	 */
.
136a
	/*
	 *  since the bss/data segments are now shareable,
	 *  any mmu info about this process is now stale
	 *  (i.e. has bad properties) and has to be discarded.
	 */
.
118d
44c
	clearmmucache();	/* so child doesn't inherit any of your mappings */
.
## diffname port/sysproc.c 1991/0605
## diff -e /n/bootesdump/1991/0529/sys/src/9/port/sysproc.c /n/bootesdump/1991/0605/sys/src/9/port/sysproc.c
547a
/*
long
syslkbrk(ulong *arg)
{
	ulong addr;
	Orig *o;
	Seg *s;

	addr = arg[0];
	s = &u->p->seg[LSEG];
	if(addr < LKSEGBASE)
		error(Esegaddr);

	/* If we have never seen a lock segment create one */
	if(s->o == 0) {
		s->proc = u->p;
		s->minva = LKSEGBASE;
		s->maxva = addr;
		o = neworig(s->minva, (addr-LKSEGBASE)>>PGSHIFT, OWRPERM, 0);
		o->minca = 0;
		o->maxca = 0;
		s->o = o;
		s->mod = 0;
	}
	if(addr < s->maxva)
		return 0;
	if(segaddr(&u->p->seg[LSEG], s->minva, addr) == 0) {
		pprint("bad segaddr in brk\n");
		pexit("Suicide", 0);
		error(Esegaddr);

	}
	return 0;
}
*/
.
## diffname port/sysproc.c 1991/0606
## diff -e /n/bootesdump/1991/0605/sys/src/9/port/sysproc.c /n/bootesdump/1991/0606/sys/src/9/port/sysproc.c
582d
552,580c
	return ibrk(arg[0], LSEG);
.
550c
syslkbrk_(ulong *arg)
.
548c

.
528,546c
	return ibrk(arg[0], BSEG);
.
341c
	p->seg[BSEG].endseg = bssend;
.
128d
## diffname port/sysproc.c 1991/0607
## diff -e /n/bootesdump/1991/0606/sys/src/9/port/sysproc.c /n/bootesdump/1991/0607/sys/src/9/port/sysproc.c
330c
	o = neworig(d, (b-d)>>PGSHIFT, OWRPERM|OISMEM, 0);
.
316c
		o = neworig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED|OISMEM, tc);
.
314c
	o = lookorig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED|OISMEM, tc);
.
300c
		o = neworig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED|OISMEM, tc);
.
298c
	o = lookorig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED|OISMEM, tc);
.
253c
	s->o = neworig(TSTKTOP-(spage<<PGSHIFT), spage, OWRPERM|OISMEM, 0);
.
69c
	s->o = neworig(s->minva, n, OWRPERM|OISMEM, 0);
.
## diffname port/sysproc.c 1991/0614
## diff -e /n/bootesdump/1991/0607/sys/src/9/port/sysproc.c /n/bootesdump/1991/0614/sys/src/9/port/sysproc.c
498a
	poperror();
.
437a
		poperror();
.
337a
	poperror();
.
208a
	close(tc);
.
207d
## diffname port/sysproc.c 1991/0619
## diff -e /n/bootesdump/1991/0614/sys/src/9/port/sysproc.c /n/bootesdump/1991/0619/sys/src/9/port/sysproc.c
240c
		nbytes += (vmemchr(a, 0, ~0) - a) + 1;
.
## diffname port/sysproc.c 1991/0705
## diff -e /n/bootesdump/1991/0619/sys/src/9/port/sysproc.c /n/bootesdump/1991/0705/sys/src/9/port/sysproc.c
536c
	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);
.
534c
syssegattach(ulong *arg)
.
530c
	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");
.
528c
syssegbrk(ulong *arg)
.
524,526d
503a
	u->p->egrp = eg;
.
502a
	closeegrp(u->p->egrp);
.
493c
		envcpy(eg, u->p->egrp);
.
479a
		closeegrp(eg);
.
477a
	eg = newegrp();
.
475a
	Egrp *eg;
.
439a

.
359c
	 *  At this point, the mmu contains info about the old address
.
357a
	poperror();

.
346,356c
	s = p->seg[ESEG];
	p->seg[SSEG] = s;
	s->base = USTKTOP-USTKSIZE;
	s->top = USTKTOP;
	relocateseg(s, TSTKTOP-USTKTOP);
	p->seg[ESEG] = 0;
.
342a
	close(tc);

.
341c
	/* BSS. Zero fill on demand */
	p->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT);
.
338,339d
325,336c
	/* Attached by hand */
	incref(img);
	s->image = img;
	s->fstart = ts->fstart+ts->flen;
	s->flen = exec.data;
.
309,323c
	/* Data. Shared. */
	s = newseg(SG_DATA, t, (d-t)>>PGSHIFT);
	p->seg[DSEG] = s;
.
293,307c
	/* 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;
.
287,291c
	f = u->p->fgrp;
	for(i=0; i<=f->maxfd; i++)
		fdclose(i, CCEXEC);
.
282c
	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;
.
280c
	 * Committed.  Free old memory. Special segments are maintained accross exec
.
278a
	if(waserror())
		pexit("fatal exec error", 0);

.
267c
		if(indir && *argp==0) {
.
265a

.
251,255c
	 
	p->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG);
.
240c
		nbytes += (vmemchr(a, 0, 0xFFFFFFFF) - a) + 1;
.
211a
	poperror();
.
162a
	Fgrp *f;
	Image *img;
.
154d
150c
	Segment *s, *ts;
.
129d
127c

.
124a

.
110,113c
	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);

.
53,107d
51a
	/* 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]);

.
36a

	/* Page va of upage used as check in mapstack */
.
32d
28d
24c
	Segment *s;
.
## diffname port/sysproc.c 1991/0706
## diff -e /n/bootesdump/1991/0705/sys/src/9/port/sysproc.c /n/bootesdump/1991/0706/sys/src/9/port/sysproc.c
532,533c
	len = arg[1];
.
528c
	from = PGROUND(arg[0]);
	s = seg(u->p, from, 1);
.
288a
	close(tc);
.
277,278d
273d
259a
	ts->flushme = 1;
.
131a

.
## diffname port/sysproc.c 1991/0707
## diff -e /n/bootesdump/1991/0706/sys/src/9/port/sysproc.c /n/bootesdump/1991/0707/sys/src/9/port/sysproc.c
286d
281a
	p->seg[ESEG] = 0;
.
## diffname port/sysproc.c 1991/0709
## diff -e /n/bootesdump/1991/0707/sys/src/9/port/sysproc.c /n/bootesdump/1991/0709/sys/src/9/port/sysproc.c
241,248c
	for(i = SSEG; i <= BSEG; i++) {
		putseg(p->seg[i]);
		p->seg[i] = 0;	    /* prevent a second free if we have an error */
	}
.
207c
		errors("too many arguments");
.
31,33c

.
## diffname port/sysproc.c 1991/0710
## diff -e /n/bootesdump/1991/0709/sys/src/9/port/sysproc.c /n/bootesdump/1991/0710/sys/src/9/port/sysproc.c
301c
	return (USTKTOP-BY2WD);	/* address of user-level clock */
.
178c
	nbytes = BY2WD;		/* hole for profiling clock at top of stack */
.
## diffname port/sysproc.c 1991/0712
## diff -e /n/bootesdump/1991/0710/sys/src/9/port/sysproc.c /n/bootesdump/1991/0712/sys/src/9/port/sysproc.c
534c
	mfreeseg(s, from, pages);
.
529c
	if(from+pages*BY2PG > s->top) {
.
527c
	pages = (arg[1]+BY2PG-1)/BY2PG;
.
520c
	ulong from, pages;
.
## diffname port/sysproc.c 1991/0723
## diff -e /n/bootesdump/1991/0712/sys/src/9/port/sysproc.c /n/bootesdump/1991/0723/sys/src/9/port/sysproc.c
490a
	s = 0;
.
291c
	execpc(entry);
.
267c
	s->flen = data;
.
257c
	ts->flen = sizeof(Exec)+text;
.
168,170c
	data = l2be(exec.data);
	bss = l2be(exec.bss);
	t = (UTZERO+sizeof(Exec)+text+(BY2PG-1)) & ~(BY2PG-1);
	d = (t + data + (BY2PG-1)) & ~(BY2PG-1);
	bssend = t + data + bss;
.
135,138c
	magic = l2be(exec.magic);
	text = l2be(exec.text);
	entry = l2be(exec.entry);
	if(n==sizeof(Exec) && magic==AOUT_MAGIC){
		if((text&KZERO)
		|| entry < UTZERO+sizeof(Exec)
		|| entry >= UTZERO+sizeof(Exec)+text)
.
116a
	ulong magic, text, entry, data, bss;
.
98a
static ulong
l2be(long l)
{
	uchar *cp;

	cp = (uchar*)&l;
	return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3];
}

.
## diffname port/sysproc.c 1991/0724
## diff -e /n/bootesdump/1991/0723/sys/src/9/port/sysproc.c /n/bootesdump/1991/0724/sys/src/9/port/sysproc.c
410a
	strncpy(u->error, errstrtab[0], ERRLEN);
.
272a
	unlock(img);
.
266a
	/* attachimage returns a locked cache image */
.
## diffname port/sysproc.c 1991/0806
## diff -e /n/bootesdump/1991/0724/sys/src/9/port/sysproc.c /n/bootesdump/1991/0806/sys/src/9/port/sysproc.c
564a

long
sysrendezvous(ulong *arg)
{
	Proc *p, *d, **l;
	int s, tag;
	ulong val;

	tag = arg[0];
	l = &REND(u->p->pgrp, tag);

	lock(u->p->pgrp);
	for(p = *l; p; p = p->rendhash) {
		if(p->rendtag == tag) {
			*l = p->rendhash;
			val = p->rendval;
			p->rendval = arg[1];

			if(p->state != Rendezvous)
				panic("rendezvous");
			ready(p);
			unlock(u->p->pgrp);
			return val;	
		}
		l = &p->rendhash;
	}

	/* Going to sleep here */
	p = u->p;
	p->rendtag = tag;
	p->rendval = arg[1];
	p->rendhash = *l;
	*l = p;

	unlock(p->pgrp);

	s = splhi();
	u->p->state = Rendezvous;
	sched();
	splx(s);

	return u->p->rendval;
}
.
## diffname port/sysproc.c 1991/0807
## diff -e /n/bootesdump/1991/0806/sys/src/9/port/sysproc.c /n/bootesdump/1991/0807/sys/src/9/port/sysproc.c
601a
	unlock(p->pgrp);
.
599,600d
583,584c
			while(p->state != Rendezvous)
				;
.
66a
	if(flag & Forkeg) {
		p->egrp = u->p->egrp;			/* Environment group */
		incref(p->egrp);
	}
	else {
		p->egrp = newegrp();
		envcpy(p->egrp, u->p->egrp);
	}

.
64,65c
	if(flag & Forkpg) {
		p->pgrp = u->p->pgrp;			/* Process groups */
		incref(p->pgrp);
	}
	else {
		p->pgrp = newpgrp();
		pgrpcpy(p->pgrp, u->p->pgrp);
	}
.
61,62c
	if(flag & Forkfd)
		p->fgrp = dupfgrp(u->p->fgrp);
	else {
		p->fgrp = u->p->fgrp;
		incref(p->fgrp);
	}
.
59d
30c
	/*
	 * used to compute last valid system stack address for copy
	 */
	int lastvar;	
.
22a
	return rfork(Forkfd|Forkeg|Forkpg);
}

/* This call will obsolete fork */
long
sysrfork(ulong *arg)
{
	return rfork(arg[0]);
}

long
rfork(ulong flag)
{
.
11a
long	rfork(ulong);
.
## diffname port/sysproc.c 1991/0808
## diff -e /n/bootesdump/1991/0807/sys/src/9/port/sysproc.c /n/bootesdump/1991/0808/sys/src/9/port/sysproc.c
416c
			if(vmemchr(status, 0, ERRLEN) == 0)
				status = inval;
.
413c
			status = inval;
.
408a
	char *inval = "invalid exit string";
.
100a
	else {
		p->egrp = u->p->egrp;			/* Environment group */
		incref(p->egrp);
	}
.
94,97d
91a
	else {
		p->pgrp = u->p->pgrp;			/* Process groups */
		incref(p->pgrp);
	}
.
85,88d
79c
	else{
.
24c
	return rfork(Forkfd);
.
## diffname port/sysproc.c 1991/0820
## diff -e /n/bootesdump/1991/0808/sys/src/9/port/sysproc.c /n/bootesdump/1991/0820/sys/src/9/port/sysproc.c
106d
## diffname port/sysproc.c 1991/0919
## diff -e /n/bootesdump/1991/0820/sys/src/9/port/sysproc.c /n/bootesdump/1991/0919/sys/src/9/port/sysproc.c
105a
		/*
		 *  use u->p instead of p, because we
		 *  don't trust the compiler, after a
		 *  gotolabel, to find the correct contents
		 *  of a local variable.
		 */
		p = u->p;
.
## diffname port/sysproc.c 1991/0926
## diff -e /n/bootesdump/1991/0919/sys/src/9/port/sysproc.c /n/bootesdump/1991/0926/sys/src/9/port/sysproc.c
124a
	unlock(&u->p->exl);
.
123a
	lock(&u->p->exl);
.
## diffname port/sysproc.c 1991/1105
## diff -e /n/bootesdump/1991/0926/sys/src/9/port/sysproc.c /n/bootesdump/1991/1105/sys/src/9/port/sysproc.c
480,481d
343d
291,293d
130a
	memmove(p->user, u->p->user, NAMELEN);
.
17c
	print("[%s %s %d] r1 = %d\n", u->p->user, u->p->text, u->p->pid, arg[0]);
.
## diffname port/sysproc.c 1991/1110
## diff -e /n/bootesdump/1991/1105/sys/src/9/port/sysproc.c /n/bootesdump/1991/1110/sys/src/9/port/sysproc.c
357a
	if(p->hang)
		p->procctl = Proc_stopme;

.
101a
	p->hang = u->p->hang;
	p->procmode = u->p->procmode;

.
72,74c
	/* Refs */
.
56,59c
	/* Save time: only copy u-> data and useful stack */
	clearmmucache();
.
## diffname port/sysproc.c 1991/1115
## diff -e /n/bootesdump/1991/1110/sys/src/9/port/sysproc.c /n/bootesdump/1991/1115/sys/src/9/port/sysproc.c
511a
	USED(arg);
.
502a
	USED(arg);
.
445a
	USED(arg);
.
395a
	USED(a);
.
23a
	USED(arg);
.
## diffname port/sysproc.c 1991/1214
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/sysproc.c /n/bootesdump/1991/1214/sys/src/9/port/sysproc.c
361c
	return execregs(entry, ssize, nargs);
.
348,351d
## diffname port/sysproc.c 1991/1216
## diff -e /n/bootesdump/1991/1214/sys/src/9/port/sysproc.c /n/bootesdump/1991/1216/sys/src/9/port/sysproc.c
353c
	qunlock(&p->debug);
.
348c
	qlock(&p->debug);
.
## diffname port/sysproc.c 1991/1219
## diff -e /n/bootesdump/1991/1216/sys/src/9/port/sysproc.c /n/bootesdump/1991/1219/sys/src/9/port/sysproc.c
400c
	if(arg[0] == 0)
		sched();
	else
		tsleep(&u->p->sleep, return0, 0, arg[0]);

.
## diffname port/sysproc.c 1992/0103
## diff -e /n/bootesdump/1991/1219/sys/src/9/port/sysproc.c /n/bootesdump/1992/0103/sys/src/9/port/sysproc.c
347d
138d
58d
## diffname port/sysproc.c 1992/0111
## diff -e /n/bootesdump/1992/0103/sys/src/9/port/sysproc.c /n/bootesdump/1992/0111/sys/src/9/port/sysproc.c
457c
	strncpy(u->error, Enoerror, ERRLEN);
.
7c
#include	"../port/error.h"
.
## diffname port/sysproc.c 1992/0114
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/sysproc.c /n/bootesdump/1992/0114/sys/src/9/port/sysproc.c
594c
		error(Ebadarg);
.
588c
		error(Ebadarg);
.
568c
		error(Ebadarg);
.
563c
	error(Ebadarg);
.
538c
	error(Ebadarg);
.
531c
					error(Ebadarg);
.
262c
		error(Enovmem);
.
## diffname port/sysproc.c 1992/0120
## diff -e /n/bootesdump/1992/0114/sys/src/9/port/sysproc.c /n/bootesdump/1992/0120/sys/src/9/port/sysproc.c
6d
## diffname port/sysproc.c 1992/0129
## diff -e /n/bootesdump/1992/0120/sys/src/9/port/sysproc.c /n/bootesdump/1992/0129/sys/src/9/port/sysproc.c
480a
	else
		*pg->crypt = *u->p->pgrp->crypt;
.
## diffname port/sysproc.c 1992/0131
## diff -e /n/bootesdump/1992/0129/sys/src/9/port/sysproc.c /n/bootesdump/1992/0131/sys/src/9/port/sysproc.c
52c
	p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF));
.
## diffname port/sysproc.c 1992/0307
## diff -e /n/bootesdump/1992/0131/sys/src/9/port/sysproc.c /n/bootesdump/1992/0307/sys/src/9/port/sysproc.c
105,108c
		 *  use u->p instead of p, because we don't trust the compiler, after a
		 *  gotolabel, to find the correct contents of a local variable.
.
100,102d
70c
	incref(u->dot);					/* File descriptors etc. */
.
59c
	n = (n+32) & ~(BY2WD-1);
.
## diffname port/sysproc.c 1992/0309
## diff -e /n/bootesdump/1992/0307/sys/src/9/port/sysproc.c /n/bootesdump/1992/0309/sys/src/9/port/sysproc.c
436a
sys__wait__(ulong *arg)			/* binary compatibility: BUG */
{
	int i;

	struct oldWaitmsg
	{
		int	pid;		/* of loved one */
		int	status;		/* unused; a vestige */
		long	time[3];	/* of loved one & descendants */
		char	msg[ERRLEN];
	} *wp;
	Waitmsg w;

	if(arg[0]){
		validaddr(arg[0], sizeof(struct oldWaitmsg), 1);
		evenaddr(arg[0]);
		i = pwait(&w);
		wp = (struct oldWaitmsg*)arg[0];
		wp->pid = atoi(w.pid);
		wp->status = 0;
		wp->time[TUser] = atoi(w.time+TUser*NUMSIZE);
		wp->time[TSys] = atoi(w.time+TSys*NUMSIZE);
		wp->time[TReal] = atoi(w.time+TReal*NUMSIZE);
		memmove(wp->msg, w.msg, ERRLEN);
		return i;
	}
	return pwait(0);
}

long
.
## diffname port/sysproc.c 1992/0321
## diff -e /n/bootesdump/1992/0309/sys/src/9/port/sysproc.c /n/bootesdump/1992/0321/sys/src/9/port/sysproc.c
2c
#include	"../port/lib.h"
.
## diffname port/sysproc.c 1992/0420
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/sysproc.c /n/bootesdump/1992/0420/sys/src/9/port/sysproc.c
43d
40a
	int n, on, i;
.
39d
## diffname port/sysproc.c 1992/0428
## diff -e /n/bootesdump/1992/0420/sys/src/9/port/sysproc.c /n/bootesdump/1992/0428/sys/src/9/port/sysproc.c
515a
	u->p->noteid = incref(&noteidalloc);
.
113a
	if((flag&FORKNTG) == 0)
		p->noteid = u->p->noteid;
.
92c
		p->egrp = u->p->egrp;
.
87,89c
	/* Environment group */
	if(flag & (FORKEVG|FORKCEVG)) {
		if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
			error(Ebadarg);
		if(flag & FORKEVG) {
			p->egrp = newegrp();
			envcpy(p->egrp, u->p->egrp);
		}
		else
		if(flag & FORKCEVG)
			p->egrp = newegrp();
.
83c
		p->pgrp = u->p->pgrp;
.
78,80c
	/* Process groups */
	if(flag & (FORKNSG|FORKCNSG)) {	
		if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
			error(Ebadarg);
		if(flag & FORKNSG) {
			p->pgrp = newpgrp();
			pgrpcpy(p->pgrp, u->p->pgrp);
		}
		else
		if(flag & FORKCNSG)
			p->pgrp = newpgrp();
.
71,73c
	if(flag & FORKMEM)
		error(Egreg);

	/* File descriptors */
	if(flag & (FORKFDG|FORKCFDG)) {
		if((flag & (FORKFDG|FORKCFDG)) == (FORKFDG|FORKCFDG))
			error(Ebadarg);
		if(flag & FORKFDG)
			p->fgrp = dupfgrp(u->p->fgrp);
		else
		if(flag & FORKCFDG)
			p->fgrp = newfgrp();
	}
	else {
.
69c
	incref(u->dot);	
.
47a
	p = u->p;
	if((flag&FORKPCS) == 0) {
		if(flag & (FORKNSG|FORKCNSG)) {
			if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
				error(Ebadarg);
			opg = p->pgrp;
			p->pgrp = newpgrp();
			if(flag & FORKNSG)
				pgrpcpy(p->pgrp, opg);
			closepgrp(opg);
		}
		if(flag & (FORKEVG|FORKCEVG)) {
			if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
				error(Ebadarg);
			oeg = p->egrp;
			p->egrp = newegrp();
			if(flag & FORKEVG)
				envcpy(p->egrp, oeg);
			closeegrp(oeg);
		}
		if(flag & FORKFDG)
			error(Ebadarg);
		if(flag & FORKCFDG) {
			ofg = p->fgrp;
			p->fgrp = newfgrp();
			closefgrp(ofg);
		}
		if(flag & FORKNTG)
			p->noteid = incref(&noteidalloc);
		if(flag & FORKMEM)
			error(Ebadarg);
		return 0;
	}

.
42a
	Pgrp *opg;
	Egrp *oeg;
	Fgrp *ofg;
.
26a
long
sys__rfork__(ulong *arg)
{
	return rfork(arg[0]|FORKPCS);
}

.
24c
	return rfork(FORKFDG|FORKPCS);
.
## diffname port/sysproc.c 1992/0430
## diff -e /n/bootesdump/1992/0428/sys/src/9/port/sysproc.c /n/bootesdump/1992/0430/sys/src/9/port/sysproc.c
194,195c
	memmove(p->text, parent->text, NAMELEN);
	memmove(p->user, parent->user, NAMELEN);
.
187,190c
	p->fpstate = parent->fpstate;
	lock(&parent->exl);
	parent->nchild++;
	unlock(&parent->exl);
.
185c
		p->noteid = parent->noteid;
.
182,183c
	p->parent = parent;
	p->parentpid = parent->pid;
	if(flag&FORKNOW)
		p->parentpid = 1;
.
166,167c
	p->hang = parent->hang;
	p->procmode = parent->procmode;
.
162c
		p->egrp = parent->egrp;
.
155c
			envcpy(p->egrp, parent->egrp);
.
151,152d
145c
		p->pgrp = parent->pgrp;
.
142a
			*p->pgrp->crypt = *parent->pgrp->crypt;
		}
.
141c
		if(flag & FORKCNSG) {
.
138c
			pgrpcpy(p->pgrp, parent->pgrp);
.
134,135d
128c
		p->fgrp = parent->fgrp;
.
122c
			p->fgrp = dupfgrp(parent->fgrp);
.
119,120d
114,116d
108,109c
		if(parent->seg[i])
			p->seg[i] = dupseg(parent->seg[i], n);
.
106a
	n = flag & FORKMEM;
.
91a
	parent = u->p;
.
89a
	/* Check flags before we commit */
	if((flag & (FORKFDG|FORKCFDG)) == (FORKFDG|FORKCFDG))
		error(Ebadarg);
	if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
		error(Ebadarg);
	if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
		error(Ebadarg);
.
86c
		if(flag & (FORKMEM|FORKNOW))
.
65a
			else
				*p->pgrp->crypt = *opg->crypt;
.
43c
	Proc *p, *parent;
.
21c
sys__fork__(ulong *arg)
.
19a
enum					/* Argument to forkpgrp call */
{
	FPall 	  = 0,			/* Concession to back portablility */
	FPnote 	  = 1,
	FPnamespc = 2,
	FPenv	  = 4,
	FPclear	  = 8,
};

.
## diffname port/sysproc.c 1992/0501
## diff -e /n/bootesdump/1992/0430/sys/src/9/port/sysproc.c /n/bootesdump/1992/0501/sys/src/9/port/sysproc.c
199c
	if((flag&RFNOTEG) == 0)
.
197c
	if(flag&RFNOWAIT)
.
171c
		if(flag & RFCENVG)
.
165,166c
	if(flag & (RFENVG|RFCENVG)) {
		if(flag & RFENVG) {
.
154c
		if(flag & RFCNAMEG) {
.
148,149c
	if(flag & (RFNAMEG|RFCNAMEG)) {	
		if(flag & RFNAMEG) {
.
139c
		if(flag & RFCFDG)
.
135,136c
	if(flag & (RFFDG|RFCFDG)) {
		if(flag & RFFDG)
.
126c
	n = flag & RFMEM;
.
106c
	if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG))
.
104c
	if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG))
.
102c
	if((flag & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
.
97c
		if(flag & (RFMEM|RFNOWAIT))
.
95c
		if(flag & RFNOTEG)
.
90c
		if(flag & RFCFDG) {
.
88c
		if(flag & RFFDG)
.
84c
			if(flag & RFENVG)
.
79,80c
		if(flag & (RFENVG|RFCENVG)) {
			if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG))
.
73c
			if(flag & RFNAMEG)
.
67,69c
	if((flag&RFPROC) == 0) {
		if(flag & (RFNAMEG|RFCNAMEG)) {
			if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG))
.
39c
	return rfork(arg[0]|RFPROC);
.
33c
	return rfork(RFFDG|RFPROC);
.
## diffname port/sysproc.c 1992/0520
## diff -e /n/bootesdump/1992/0501/sys/src/9/port/sysproc.c /n/bootesdump/1992/0520/sys/src/9/port/sysproc.c
651a
	return 0;		/* not reached */
.
557a
	return 0;	/* not reached */
.
509a
	return 0;		/* not reached */
.
## diffname port/sysproc.c 1992/0603
## diff -e /n/bootesdump/1992/0520/sys/src/9/port/sysproc.c /n/bootesdump/1992/0603/sys/src/9/port/sysproc.c
574c
sys__forkpgrp__(ulong *arg)
.
## diffname port/sysproc.c 1992/0607
## diff -e /n/bootesdump/1992/0603/sys/src/9/port/sysproc.c /n/bootesdump/1992/0607/sys/src/9/port/sysproc.c
171d
153,154c
		else {
.
139d
88,89c
		if(flag & RFFDG) {
			ofg = p->fgrp;
			p->fgrp = dupfgrp(ofg);
			closefgrp(ofg);
		}
		else
.
## diffname port/sysproc.c 1992/0622
## diff -e /n/bootesdump/1992/0607/sys/src/9/port/sysproc.c /n/bootesdump/1992/0622/sys/src/9/port/sysproc.c
572,613d
525,554d
65a
	flag = arg[0];
.
60a
	Segment *s;
	int n, on, i;
	Proc *p, *parent;
	ulong usp, upa, pid, flag;
.
46,55d
30,43d
20,28d
11d
## diffname port/sysproc.c 1992/0623
## diff -e /n/bootesdump/1992/0622/sys/src/9/port/sysproc.c /n/bootesdump/1992/0623/sys/src/9/port/sysproc.c
142,144d
139,140c
		p->egrp = smalloc(sizeof(Egrp));
		p->egrp->ref = 1;
		if(flag & RFENVG)
.
113,114c
		else {
			p->fgrp = smalloc(sizeof(Fgrp));
			p->fgrp->ref = 1;
		}
.
67c
			p->fgrp = smalloc(sizeof(Fgrp));
			p->fgrp->ref = 1;
.
54c
			p->egrp = smalloc(sizeof(Egrp));
			p->egrp->ref = 1;
.
## diffname port/sysproc.c 1992/0628
## diff -e /n/bootesdump/1992/0623/sys/src/9/port/sysproc.c /n/bootesdump/1992/0628/sys/src/9/port/sysproc.c
501c
	pprint("deprecated system call\n");
.
## diffname port/sysproc.c 1992/0711
## diff -e /n/bootesdump/1992/0628/sys/src/9/port/sysproc.c /n/bootesdump/1992/0711/sys/src/9/port/sysproc.c
631c
	Proc *p, **l;
.
509,510d
216d
211c
	Chan *tc;
.
209c
	ulong t, d, b;
.
30c
	ulong upa, pid, flag;
.
27,28c
	int n, i;
.
22d
## diffname port/sysproc.c 1992/0714
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/sysproc.c /n/bootesdump/1992/0714/sys/src/9/port/sysproc.c
14a
	xsummary();
.
## diffname port/sysproc.c 1992/0715
## diff -e /n/bootesdump/1992/0714/sys/src/9/port/sysproc.c /n/bootesdump/1992/0715/sys/src/9/port/sysproc.c
176,178d
171a
	else {
		lock(&parent->exl);
		parent->nchild++;
		unlock(&parent->exl);
	}
.
## diffname port/sysproc.c 1992/0802
## diff -e /n/bootesdump/1992/0715/sys/src/9/port/sysproc.c /n/bootesdump/1992/0802/sys/src/9/port/sysproc.c
318d
310a
	/*
	 * 8-byte align SP for those (e.g. sparc) that need it.
	 * execregs() will subtract another 4 bytes for argc.
	 */
	if((ssize+4) & 7)
		ssize += 4;
.
## diffname port/sysproc.c 1992/0923
## diff -e /n/bootesdump/1992/0802/sys/src/9/port/sysproc.c /n/bootesdump/1992/0923/sys/src/9/port/sysproc.c
310a

.
## diffname port/sysproc.c 1992/0928
## diff -e /n/bootesdump/1992/0923/sys/src/9/port/sysproc.c /n/bootesdump/1992/0928/sys/src/9/port/sysproc.c
422c
	s += 2;
	n -= 2;		/* skip #! */
.
133d
129,131c
		else
.
126,127c
		p->pgrp = newpgrp();
		if(flag & RFNAMEG)
.
35c
		flag = arg[0];
.
## diffname port/sysproc.c 1992/1104
## diff -e /n/bootesdump/1992/0928/sys/src/9/port/sysproc.c /n/bootesdump/1992/1104/sys/src/9/port/sysproc.c
105,106c
			p->seg[i] = dupseg(parent->seg, i, n);
	
.
## diffname port/sysproc.c 1992/1206
## diff -e /n/bootesdump/1992/1104/sys/src/9/port/sysproc.c /n/bootesdump/1992/1206/sys/src/9/port/sysproc.c
646c
			/* Easy race avoidance */
.
618a
	flushmmu();
.
348c
	 * Committed.
	 * Free old memory.
	 * Special segments are maintained accross exec
.
35c
	flag = arg[0];
.
## diffname port/sysproc.c 1993/0227
## diff -e /n/bootesdump/1992/1206/sys/src/9/port/sysproc.c /n/bootesdump/1993/0227/sys/src/9/port/sysproc.c
304c
		nbytes += (vmemchr(a, 0, 0x7FFFFFFF) - a) + 1;
.
## diffname port/sysproc.c 1993/0324
## diff -e /n/bootesdump/1993/0227/sys/src/9/port/sysproc.c /n/bootesdump/1993/0324/sys/src/9/port/sysproc.c
517c
	memmove(u->error, tmp, ERRLEN);
.
515a
	memmove(tmp, (char*)arg[0], ERRLEN);
.
514a
	char tmp[ERRLEN];

.
## diffname port/sysproc.c 1993/0330
## diff -e /n/bootesdump/1993/0324/sys/src/9/port/sysproc.c /n/bootesdump/1993/0330/sys/src/9/port/sysproc.c
129,130d
45,46d
## diffname port/sysproc.c 1993/0501
## diff -e /n/bootesdump/1993/0330/sys/src/9/port/sysproc.c /n/fornaxdump/1993/0501/sys/src/brazil/port/sysproc.c
671c
	return up->rendval;
.
666,667c
	unlock(up->pgrp);
	up->state = Rendezvous;
.
659,663c
	up->rendtag = tag;
	up->rendval = arg[1];
	up->rendhash = *l;
	*l = up;
.
652c
			unlock(up->pgrp);
.
642c
	lock(up->pgrp);
.
640c
	l = &REND(up->pgrp, tag);
.
607c
	s = seg(up, from, 1);
.
591c
	up->seg[i] = 0;
.
586a
	/* Check we are not detaching the current stack segment */
.
578,579c
			if((addr >= s->base && addr < s->top) || 
			   (s->top == s->base && addr == s->base))
.
576c
		if(s = up->seg[i]) {
.
574a
	addr = arg[0];
.
571a
	ulong addr;
.
565c
	return segattach(up, arg[0], (char*)arg[1], arg[2], arg[3]);
.
556a
	}
.
545,555c
	addr = arg[0];
	for(i = 0; i < NSEG; i++) {
		s = up->seg[i];
		if(s == 0 || addr < s->base || addr >= s->top)
			continue;
		switch(s->type&SG_TYPE) {
		case SG_TEXT:
		case SG_DATA:
			error(Ebadarg);
		default:
			return ibrk(arg[1], i);
.
543a
	ulong addr;
	Segment *s;
.
542d
534c
	if(up->notified == 0)
.
526c
	up->notify = (int(*)(void*, char*))(arg[0]);
.
514,516c
	e = (char*)arg[0];
	memmove(tmp, e, ERRLEN);
	memmove(e, up->error, ERRLEN);
	memmove(up->error, tmp, ERRLEN);
.
511c
	char *e, tmp[ERRLEN];
.
456c
		tsleep(&up->sleep, return0, 0, arg[0]);
.
425c
	for(;;) {
.
400,407c
	qlock(&up->debug);
	up->nnote = 0;
	up->notify = 0;
	up->notified = 0;
	procsetup(up);
	qunlock(&up->debug);
	if(up->hang)
		up->procctl = Proc_stopme;
.
386,388c
	s = up->seg[ESEG];
	up->seg[ESEG] = 0;
	up->seg[SSEG] = s;
.
381c
	up->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT);
.
372c
	up->seg[DSEG] = s;
.
364c
	up->seg[TSEG] = ts;
.
356c
	f = up->fgrp;
.
349,350c
		putseg(up->seg[i]);
		up->seg[i] = 0;	    /* prevent a second free if we have an error */
.
341c
	memmove(up->text, elem, NAMELEN);
.
318c
	up->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG);
.
228c
		strcpy(elem, up->elem);
.
217d
201d
177,178c
	memmove(p->text, up->text, NAMELEN);
	memmove(p->user, up->user, NAMELEN);
.
173c
	p->fpstate = up->fpstate;
.
171c
		p->noteid = up->noteid;
.
166,168c
		lock(&up->exl);
		up->nchild++;
		unlock(&up->exl);
.
148,162c
	/* Craft a return frame which will cause the child to pop out of
	 * the scheduler in user mode with the return register zero
	 */
	forkchild(p, up->dbgreg);
	
	p->parent = up;
	p->parentpid = up->pid;
.
145,146c
	p->hang = up->hang;
	p->procmode = up->procmode;
.
141c
		p->egrp = up->egrp;
.
138c
			envcpy(p->egrp, up->egrp);
.
129c
		p->pgrp = up->pgrp;
.
126c
			pgrpcpy(p->pgrp, up->pgrp);
.
118c
		p->fgrp = up->fgrp;
.
111c
			p->fgrp = dupfgrp(up->fgrp);
.
102,106c
		if(up->seg[i])
			p->seg[i] = dupseg(up->seg, i, n);
.
91,97c
	memmove(p->note, up->note, sizeof(p->note));
	p->nnote = up->nnote;
	p->notified = 0;
	p->lastnote = up->lastnote;
	p->notify = up->notify;
	p->ureg = 0;
	p->dbgreg = 0;
.
86,89c
	p->fpsave = up->fpsave;
	p->scallnr = up->scallnr;
	p->s = up->s;
	p->nerrlab = 0;
	p->slash = up->slash;
	p->dot = up->dot;
	incref(p->dot);	
.
84d
70c
			up->noteid = incref(&noteidalloc);
.
64,66c
			ofg = up->fgrp;
			up->fgrp = smalloc(sizeof(Fgrp));
			up->fgrp->ref = 1;
.
58,59c
			ofg = up->fgrp;
			up->fgrp = dupfgrp(ofg);
.
54c
				envcpy(up->egrp, oeg);
.
50,52c
			oeg = up->egrp;
			up->egrp = smalloc(sizeof(Egrp));
			up->egrp->ref = 1;
.
44c
				pgrpcpy(up->pgrp, opg);
.
41,42c
			opg = up->pgrp;
			up->pgrp = newpgrp();
.
36d
27,33c
	ulong pid, flag;
.
23c
	Proc *p;
	int n, i;
.
15,16c
	Chan *c;

	c = fdtochan(arg[0], -1, 0, 0);
	ptpath(c->path, (char*)arg[1], arg[2]);
.
## diffname port/sysproc.c 1993/0502
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/sysproc.c /n/fornaxdump/1993/0502/sys/src/brazil/port/sysproc.c
376c
	relocateseg(s, USTKTOP-TSTKTOP);
.
## diffname port/sysproc.c 1993/0725
## diff -e /n/fornaxdump/1993/0502/sys/src/brazil/port/sysproc.c /n/fornaxdump/1993/0725/sys/src/brazil/port/sysproc.c
320a
print("arg[%d] %s\n", i, *argp);
.
296a
print("ssize %d spage %lux\n", ssize, spage);
.
## diffname port/sysproc.c 1993/0727
## diff -e /n/fornaxdump/1993/0725/sys/src/brazil/port/sysproc.c /n/fornaxdump/1993/0727/sys/src/brazil/port/sysproc.c
322d
297c

.
## diffname port/sysproc.c 1993/0829
## diff -e /n/fornaxdump/1993/0727/sys/src/brazil/port/sysproc.c /n/fornaxdump/1993/0829/sys/src/brazil/port/sysproc.c
139c
memset(p->ltlbpid, 255, sizeof(p->ltlbpid));
.
## diffname port/sysproc.c 1993/0902
## diff -e /n/fornaxdump/1993/0829/sys/src/brazil/port/sysproc.c /n/fornaxdump/1993/0902/sys/src/brazil/port/sysproc.c
139d
## diffname port/sysproc.c 1993/1004
## diff -e /n/fornaxdump/1993/0902/sys/src/brazil/port/sysproc.c /n/fornaxdump/1993/1004/sys/src/brazil/port/sysproc.c
15,18c
	xsummary();
	print("[%s %s %d] r1 = %d\n", up->user, up->text, up->pid, arg[0]);
.
## diffname port/sysproc.c 1993/1204
## diff -e /n/fornaxdump/1993/1004/sys/src/brazil/port/sysproc.c /n/fornaxdump/1993/1204/sys/src/brazil/port/sysproc.c
162a
	p->mp = up->mp;
.
## diffname port/sysproc.c 1993/1212
## diff -e /n/fornaxdump/1993/1204/sys/src/brazil/port/sysproc.c /n/fornaxdump/1993/1212/sys/src/brazil/port/sysproc.c
163d
## diffname port/sysproc.c 1994/0106
## diff -e /n/fornaxdump/1993/1212/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0106/sys/src/brazil/port/sysproc.c
333c
		/* prevent a second free if we have an error */
		up->seg[i] = 0;
	}
	for(i = BSEG+1; i < NSEG; i++) {
		s = up->seg[i];
		if(s != 0 && (s->type&SG_CEXEC)) {
			putseg(s);
			up->seg[i] = 0;
		}
.
## diffname port/sysproc.c 1994/0515
## diff -e /n/fornaxdump/1994/0106/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0515/sys/src/brazil/port/sysproc.c
665d
663a
	unlock(up->pgrp);

.
660,662d
645,646c

			while(p->mach != 0)
.
634a
	Proc *p, **l;
.
632,633c
	int tag;
.
## diffname port/sysproc.c 1994/0603
## diff -e /n/fornaxdump/1994/0515/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0603/sys/src/brazil/port/sysproc.c
219c
	if(n==sizeof(Exec) && (magic==AOUT_MAGIC)){
.
## diffname port/sysproc.c 1994/0612
## diff -e /n/fornaxdump/1994/0603/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0612/sys/src/brazil/port/sysproc.c
219c
	if(n==sizeof(Exec) && EXEC_MAGIC(magic)){
.
15d
## diffname port/sysproc.c 1994/0617
## diff -e /n/fornaxdump/1994/0612/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0617/sys/src/brazil/port/sysproc.c
218c
	if(n==sizeof(Exec) && magic == AOUT_MAGIC){
.
## diffname port/sysproc.c 1994/0619
## diff -e /n/fornaxdump/1994/0617/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0619/sys/src/brazil/port/sysproc.c
218c
	if(n==sizeof(Exec) && (magic == AOUT_MAGIC)){
.
## diffname port/sysproc.c 1994/0727
## diff -e /n/fornaxdump/1994/0619/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0727/sys/src/brazil/port/sysproc.c
382a
	/*
	 *  '/' processes are high priority (hack to make /ip more responsive)
	 */
	if(devchar[tc->type] == L'/')
		up->priority = 1;
.
## diffname port/sysproc.c 1994/0728
## diff -e /n/fornaxdump/1994/0727/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0728/sys/src/brazil/port/sysproc.c
386a
		up->priority = 0;
	else
.
167a
	p->priority = up->priority;
	p->mp = up->mp;
.
## diffname port/sysproc.c 1994/0808
## diff -e /n/fornaxdump/1994/0728/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0808/sys/src/brazil/port/sysproc.c
391c
		up->basepri = 1;
	up->priority = up->basepri;
.
389c
		up->basepri = 0;
.
168a
	p->basepri = up->basepri;
.
## diffname port/sysproc.c 1994/0812
## diff -e /n/fornaxdump/1994/0808/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0812/sys/src/brazil/port/sysproc.c
671c
	unlock(up->rgrp);
.
659c
			unlock(up->rgrp);
.
649c
	lock(up->rgrp);
.
647c
	l = &REND(up->rgrp, tag);
.
393a
	poperror();
.
331c
	 * Special segments are maintained across exec
.
214,253d
211,212d
209d
205,207c
	for(;;){
		tc = namec(file, Aopen, OEXEC, 0);
		if(waserror()){
			close(tc);
			nexterror();
		}
		if(!indir)
			strcpy(elem, up->elem);
	
		n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec), 0);
		if(n < 2)
			error(Ebadexec);
		magic = l2be(exec.magic);
		text = l2be(exec.text);
		entry = l2be(exec.entry);
		if(n==sizeof(Exec) && (magic == AOUT_MAGIC)){
			if((text&KZERO)
			|| entry < UTZERO+sizeof(Exec)
			|| entry >= UTZERO+sizeof(Exec)+text)
				error(Ebadexec);
			break; /* for binary */
		}
	
		/*
		 * Process #! /bin/sh args ...
		 */
		memmove(line, &exec, sizeof(Exec));
		if(indir || line[0]!='#' || line[1]!='!')
			error(Ebadexec);
		n = shargs(line, n, progarg);
		if(n == 0)
			error(Ebadexec);
		indir = 1;
		/*
		 * First arg becomes complete file name
		 */
		progarg[n++] = file;
		progarg[n] = 0;
		validaddr(arg[1], BY2WD, 1);
		arg[1] += BY2WD;
		file = progarg[0];
		progarg[0] = elem;
		poperror();
.
124a
	if(flag & RFREND) {
		closergrp(up->rgrp);
		up->rgrp = newrgrp();
	}
	else {
		incref(up->rgrp);
		p->rgrp = up->rgrp;
	}

.
65a
		if(flag & RFREND) {
			closergrp(up->rgrp);
			up->rgrp = newrgrp();
		}
.
## diffname port/sysproc.c 1994/0817
## diff -e /n/fornaxdump/1994/0812/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0817/sys/src/brazil/port/sysproc.c
402c
		up->basepri = PriNormal;
.
400c
		up->basepri = PriRoot;
.
## diffname port/sysproc.c 1994/0915
## diff -e /n/fornaxdump/1994/0817/sys/src/brazil/port/sysproc.c /n/fornaxdump/1994/0915/sys/src/brazil/port/sysproc.c
401,402d
397c
	 *  '/' processes are higher priority (hack to make /ip more responsive).
.
## diffname port/sysproc.c 1995/0102
## diff -e /n/fornaxdump/1994/0915/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0102/sys/src/brazil/port/sysproc.c
399,401c
	up->nice = NiceNormal;
	if(devchar[tc->type] == L'/') {
		up->nice = NiceRoot;
		up->pri = 0;
	}
.
181,183c
	p->nice = up->nice;
	p->pri = up->pri;
	if(up->wired)
		procwired(p);
.
## diffname port/sysproc.c 1995/0105
## diff -e /n/fornaxdump/1995/0102/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0105/sys/src/brazil/port/sysproc.c
400d
## diffname port/sysproc.c 1995/0106
## diff -e /n/fornaxdump/1995/0105/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0106/sys/src/brazil/port/sysproc.c
469a
	n = arg[0];
	if(n == 0) {
		up->yield = 1;
		sched();
		return 0;
	} 
	if(MS2TK(n) == 0)
		n = TK2MS(1);
	tsleep(&up->sleep, return0, 0, n);
.
465,468c
	int n;
.
## diffname port/sysproc.c 1995/0107
## diff -e /n/fornaxdump/1995/0106/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0107/sys/src/brazil/port/sysproc.c
473c
	if(n < TK2MS(1))
.
468c
	if(n <= 0) {
.
## diffname port/sysproc.c 1995/0110
## diff -e /n/fornaxdump/1995/0107/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0110/sys/src/brazil/port/sysproc.c
469d
464a

.
400,403c
	if(devchar[tc->type] == L'/')
		up->basepri = PriRoot;
	up->priority = up->basepri;
.
181,182c
	p->priority = up->priority;
	p->basepri = up->basepri;
	p->mp = up->mp;
.
## diffname port/sysproc.c 1995/0115
## diff -e /n/fornaxdump/1995/0110/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0115/sys/src/brazil/port/sysproc.c
552,553c
	if(arg[0]!=NRSTR && !up->notified)
.
129,132c
	if(flag & RFREND)
		p->rgrp = newrgrp();
.
95c
	p->ureg = up->ureg;
.
## diffname port/sysproc.c 1995/0203
## diff -e /n/fornaxdump/1995/0115/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0203/sys/src/brazil/port/sysproc.c
569a
		case SG_STACK:
.
## diffname port/sysproc.c 1995/0324
## diff -e /n/fornaxdump/1995/0203/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0324/sys/src/brazil/port/sysproc.c
184a
	sched();
.
## diffname port/sysproc.c 1995/0329
## diff -e /n/fornaxdump/1995/0324/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0329/sys/src/brazil/port/sysproc.c
496,497c
			if(vmemchr(status, 0, ERRLEN) == 0){
				memmove(buf, status, ERRLEN);
				buf[ERRLEN-1] = 0;
				status = buf;
			}
.
488a
	char buf[ERRLEN];
.
## diffname port/sysproc.c 1995/0419
## diff -e /n/fornaxdump/1995/0329/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0419/sys/src/brazil/port/sysproc.c
468a
		p->priority = 0;
.
## diffname port/sysproc.c 1995/0421
## diff -e /n/fornaxdump/1995/0419/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0421/sys/src/brazil/port/sysproc.c
469c
		up->priority = 0;
.
## diffname port/sysproc.c 1995/0610
## diff -e /n/fornaxdump/1995/0421/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0610/sys/src/brazil/port/sysproc.c
653c
/* For binary compatibility */
.
## diffname port/sysproc.c 1995/0804
## diff -e /n/fornaxdump/1995/0610/sys/src/brazil/port/sysproc.c /n/fornaxdump/1995/0804/sys/src/brazil/port/sysproc.c
546d
524d
522c
sysdeath(ulong*)
.
457d
455c
return0(void*)
.
## diffname port/sysproc.c 1997/0327
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/sysproc.c /n/emeliedump/1997/0327/sys/src/brazil/port/sysproc.c
404c
	cclose(tc);
.
262c
		cclose(tc);
.
228c
		n = devtab[tc->type]->read(tc, &exec, sizeof(Exec), 0);
.
222c
			cclose(tc);
.
## diffname port/sysproc.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/sysproc.c /n/emeliedump/1997/0408/sys/src/brazil/port/sysproc.c
400c
	if(devtab[tc->type]->dc == L'/')
.
## diffname port/sysproc.c 1997/0606
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/sysproc.c /n/emeliedump/1997/0606/sys/src/brazil/port/sysproc.c
108,111c
		else
			p->fgrp = dupfgrp(nil);
.
58,59c
			up->fgrp = dupfgrp(nil);
.
## diffname port/sysproc.c 1997/1203
## diff -e /n/emeliedump/1997/0606/sys/src/brazil/port/sysproc.c /n/emeliedump/1997/1203/sys/src/brazil/port/sysproc.c
71,77d
63,68d
50,60d
41,42d
39a
		if(flag & RFREND) {
			org = up->rgrp;
			up->rgrp = newrgrp();
			closergrp(org);
		}
.
32,33d
30a
		if(flag & (RFMEM|RFNOWAIT))
			error(Ebadarg);
		if(flag & (RFFDG|RFCFDG)) {
			ofg = up->fgrp;
			if(flag & RFFDG)
				up->fgrp = dupfgrp(ofg);
			else
				up->fgrp = dupfgrp(nil);
			closefgrp(ofg);
		}
.
29a
	/* Check flags before we commit */
	if((flag & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
		error(Ebadarg);
	if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG))
		error(Ebadarg);
	if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG))
		error(Ebadarg);

.
26d
24a
	Rgrp *org;
.
23a
	Fgrp *ofg;
.
## diffname port/sysproc.c 1998/0512
## diff -e /n/emeliedump/1997/1203/sys/src/brazil/port/sysproc.c /n/emeliedump/1998/0512/sys/src/brazil/port/sysproc.c
671c
			return val;
.
595c
			if((addr >= s->base && addr < s->top) ||
.
474c
	return procalarm(arg[0]);
.
464c
	}
.
234c

.
220c

.
147c

.
112c
	if(flag & (RFNAMEG|RFCNAMEG)) {
.
83c
	incref(p->dot);
.
## diffname port/sysproc.c 1998/0825
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/sysproc.c /n/emeliedump/1998/0825/sys/src/brazil/port/sysproc.c
15c
	print("[%s %s %lud] r1 = %lud\n", up->user, up->text, up->pid, arg[0]);
.
## diffname port/sysproc.c 1998/0903
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/port/sysproc.c /n/emeliedump/1998/0903/sys/src/brazil/port/sysproc.c
653c
	ulong tag;
.
## diffname port/sysproc.c 1999/0108
## diff -e /n/emeliedump/1998/0903/sys/src/brazil/port/sysproc.c /n/emeliedump/1999/0108/sys/src/brazil/port/sysproc.c
611a
	qunlock(&up->seglock);
	poperror();
.
589a
	qlock(&up->seglock);
	if(waserror()){
		qunlock(&up->seglock);
		nexterror();
	}

.
385a
	qunlock(&up->seglock);
	poperror();
.
306a
	qlock(&up->seglock);
	if(waserror()){
		qunlock(&up->seglock);
		nexterror();
	}
.
97a
	qunlock(&p->seglock);
	poperror();
.
94a
	qlock(&p->seglock);
	if(waserror()){
		qunlock(&p->seglock);
		nexterror();
	}
.
## diffname port/sysproc.c 1999/0711
## diff -e /n/emeliedump/1999/0108/sys/src/brazil/port/sysproc.c /n/emeliedump/1999/0711/sys/src/brazil/port/sysproc.c
182,183c
	wm = up->wired;
	if(wm)
		procwired(p, wm->machno);
.
28a
	Mach *wm;
.
## diffname port/sysproc.c 1999/0820
## diff -e /n/emeliedump/1999/0711/sys/src/brazil/port/sysproc.c /n/emeliedump/1999/0820/sys/src/brazil/port/sysproc.c
536a
void
werrstr(char *fmt, ...)
{
	va_list va;

	if(up == nil)
		return;

	va_start(va, fmt);
	doprint(up->error, up->error+ERRLEN, fmt, va);
	va_end(va);
}

.
## diffname port/sysproc.c 2000/0322
## diff -e /n/emeliedump/1999/0820/sys/src/brazil/port/sysproc.c /n/emeliedump/2000/0322/sys/src/9/port/sysproc.c
128a
	if(flag & RFNOMNT)
		up->pgrp->noattach = 1;
.
123a
		/* inherit noattach */
		p->pgrp->noattach = up->pgrp->noattach;
.
57a
		if(flag & RFNOMNT)
			up->pgrp->noattach = 1;
.
55a
			/* inherit noattach */
			up->pgrp->noattach = opg->noattach;
.
## diffname port/sysproc.c 2000/0904
## diff -e /n/emeliedump/2000/0322/sys/src/9/port/sysproc.c /n/emeliedump/2000/0904/sys/src/9/port/sysproc.c
281c
	if(((t|d|b) & KZERO) == KZERO)
.
245c
			if((text&KZERO) == KZERO
.
## diffname port/sysproc.c 2001/0315
## diff -e /n/emeliedump/2000/0904/sys/src/9/port/sysproc.c /n/emeliedump/2001/0315/sys/src/9/port/sysproc.c
189a
	p->fixedpri = up->fixedpri;
.
## diffname port/sysproc.c 2001/0425
## diff -e /n/emeliedump/2001/0315/sys/src/9/port/sysproc.c /n/emeliedump/2001/0425/sys/src/9/port/sysproc.c
682c
	mfreeseg(s, from, (to - from) / BY2PG);
.
675,677c
	if(to > s->top) {
.
673a
	to = (from + arg[1]) & ~(BY2PG-1);
	from = PGROUND(from);
.
672c
	if(s == nil)
.
670c
	from = arg[0];
.
668c
	ulong from, to;
.
## diffname port/sysproc.c 2001/0507
## diff -e /n/emeliedump/2001/0425/sys/src/9/port/sysproc.c /n/emeliedump/2001/0507/sys/src/9/port/sysproc.c
704a
	up->rendval = ~0UL;
.
## diffname port/sysproc.c 2001/0511
## diff -e /n/emeliedump/2001/0507/sys/src/9/port/sysproc.c /n/emeliedump/2001/0511/sys/src/9/port/sysproc.c
353a

	/* copy args; easiest from new process's stack */
	n = charp - args;
	if(n > 128)	/* don't waste too much space on huge arg lists */
		n = 128;
	a = up->args;
	up->args = nil;
	free(a);
	up->args = smalloc(n);
	memmove(up->args, args, n);
	if(n>0 && up->args[n-1]!='\0'){
		/* make sure last arg is NUL-terminated */
		/* put NUL at UTF-8 character boundary */
		for(i=n-1; i>0; --i)
			if(fullrune(up->args+i, n-i))
				break;
		up->args[i] = 0;
		n = i+1;
	}
	up->nargs = n;
.
336a
	args = charp;
.
217c
	char *a, *charp, *args, *file;
.
## diffname port/sysproc.c 2001/0527
## diff -e /n/emeliedump/2001/0511/sys/src/9/port/sysproc.c /n/emeliedump/2001/0527/sys/src/9/port/sysproc.c
591a

/* compatibility for old binaries */
long
sys_errstr(ulong *arg)
{
	char *e, tmp[64];

	validaddr(arg[0], 64, 1);
	e = (char*)arg[0];
	memmove(tmp, e, 64);
	memmove(e, up->error, 64);
	memmove(up->error, tmp, 64);
	return 0;
}

.
587,589c
	memmove(tmp, e, n);
	/* make sure it's NUL-terminated */
	tmp[n-1] = '\0';
	memmove(e, up->error, n);
	e[n-1] = '\0';
	memmove(up->error, tmp, n);
.
585c
	n = arg[1];
	if(n > sizeof tmp)
		n = sizeof tmp;
	validaddr(arg[0], n, 1);
.
583c
	char *e, tmp[sizeof up->error];
	uint n;
.
576c
	doprint(up->error, up->error+ERRMAX, fmt, va);
.
536,538c
			if(vmemchr(status, 0, ERRMAX) == 0){
				memmove(buf, status, ERRMAX);
				buf[ERRMAX-1] = 0;
.
528c
	char buf[ERRMAX];
.
431c
	poperror();	/* seglock */
	poperror();	/* elem */
.
354c
	free(up->text);
	up->text = elem;
	elem = nil;	/* so waserror() won't free elem */
	USED(elem);
.
271c
		if(strlen(elem) >= sizeof progelem)
			error(Ebadexec);
		strcpy(progelem, elem);
		progarg[0] = progelem;
.
237c
			kstrdup(&elem, up->genbuf);
.
229a
	elem = nil;
	if(waserror()){
		free(elem);
		nexterror();
	}
.
218c
	char *progarg[sizeof(Exec)/2+1], *elem, progelem[64];
.
180,181c

	kstrdup(&p->text, up->text);
	kstrdup(&p->user, up->user);
.
167c
		p->parentpid = 0;
.
15a
chandebug=!chandebug;
if(chandebug)
	dumpmount();

.
14a
extern int chandebug;
extern void dumpmount(void);

.
## diffname port/sysproc.c 2001/0819
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/sysproc.c /n/emeliedump/2001/0819/sys/src/9/port/sysproc.c
576c
	return pid;
}

long
sysawait(ulong *arg)
{
	int i;
	int pid;
	Waitmsg w;
	ulong n;

	n = arg[1];
	validaddr(arg[0], n, 1);
	pid = pwait(&w);
	if(pid < 0)
		return -1;
	i = snprint((char*)arg[0], n, "%d %lud %lud %lud %q",
		w.pid,
		w.time[TUser], w.time[TSys], w.time[TReal],
		w.msg);

	return i;
.
572,574c
	int pid;
	Waitmsg w;
	OWaitmsg *ow;

	if(arg[0] == 0)
		return pwait(nil);

	validaddr(arg[0], sizeof(OWaitmsg), 1);
	evenaddr(arg[0]);
	pid = pwait(&w);
	if(pid >= 0){
		ow = (OWaitmsg*)arg[0];
		readnum(0, ow->pid, NUMSIZE, w.pid, NUMSIZE);
		readnum(0, ow->time+TUser*NUMSIZE, NUMSIZE, w.time[TUser], NUMSIZE);
		readnum(0, ow->time+TSys*NUMSIZE, NUMSIZE, w.time[TSys], NUMSIZE);
		readnum(0, ow->time+TReal*NUMSIZE, NUMSIZE, w.time[TReal], NUMSIZE);
		strncpy(ow->msg, w.msg, sizeof(ow->msg));
		ow->msg[sizeof(ow->msg)-1] = '\0';
.
570c
sys_wait(ulong *arg)
.
19,21c
	chandebug=!chandebug;
	if(chandebug)
		dumpmount();
.
15,16c
	extern int chandebug;
	extern void dumpmount(void);
.
## diffname port/sysproc.c 2001/0822
## diff -e /n/emeliedump/2001/0819/sys/src/9/port/sysproc.c /n/emeliedump/2001/0822/sys/src/9/port/sysproc.c
669d
660,667c
	return generrstr((char*)arg[0], 64);
.
655a
long
syserrstr(ulong *arg)
{
	return generrstr((char*)arg[0], arg[1]);
}

.
649,652c
	tmp[nbuf-1] = '\0';
	memmove(buf, up->syserror, nbuf);
	buf[nbuf-1] = '\0';
	memmove(up->syserror, tmp, nbuf);
.
642,647c
	validaddr((ulong)buf, nbuf, 1);
	if(nbuf > sizeof tmp)
		nbuf = sizeof tmp;
	memmove(tmp, buf, nbuf);
.
639,640c
	char tmp[sizeof up->syserror];
.
636,637c
static long
generrstr(char *buf, uint nbuf)
.
## diffname port/sysproc.c 2001/0924
## diff -e /n/emeliedump/2001/0822/sys/src/9/port/sysproc.c /n/emeliedump/2001/0924/sys/src/9/port/sysproc.c
649c
	memmove(up->syserrstr, tmp, nbuf);
.
647c
	memmove(buf, up->syserrstr, nbuf);
.
639c
	char tmp[ERRMAX];
.
632c
	doprint(up->syserrstr, up->syserrstr+ERRMAX, fmt, va);
.
## diffname port/sysproc.c 2001/1117
## diff -e /n/emeliedump/2001/0924/sys/src/9/port/sysproc.c /n/emeliedump/2001/1117/sys/src/9/port/sysproc.c
473a
	up->privatemem = 0;
.
## diffname port/sysproc.c 2001/1208
## diff -e /n/emeliedump/2001/1117/sys/src/9/port/sysproc.c /n/emeliedump/2001/1208/sys/src/9/port/sysproc.c
97a
	p->privatemem = up->privatemem;
.
## diffname port/sysproc.c 2002/0124
## diff -e /n/emeliedump/2001/1208/sys/src/9/port/sysproc.c /n/emeliedump/2002/0124/sys/src/9/port/sysproc.c
642a
	if(nbuf == 0)
		error(Ebadarg);
.
## diffname port/sysproc.c 2002/0217
## diff -e /n/emeliedump/2002/0124/sys/src/9/port/sysproc.c /n/emeliedump/2002/0217/sys/src/9/port/sysproc.c
634c
	vseprint(up->syserrstr, up->syserrstr+ERRMAX, fmt, va);
.
## diffname port/sysproc.c 2002/0228
## diff -e /n/emeliedump/2002/0217/sys/src/9/port/sysproc.c /n/emeliedump/2002/0228/sys/src/9/port/sysproc.c
198a
	p->priority = up->basepri;
.
197d
## diffname port/sysproc.c 2002/0315
## diff -e /n/emeliedump/2002/0228/sys/src/9/port/sysproc.c /n/emeliedump/2002/0315/sys/src/9/port/sysproc.c
826a
	if (isedf(up))
		edf_block(up);
.
6a
#include	"../port/edf.h"
.
## diffname port/sysproc.c 2002/0320
## diff -e /n/emeliedump/2002/0315/sys/src/9/port/sysproc.c /n/emeliedump/2002/0320/sys/src/9/port/sysproc.c
830d
827a
	unlock(up->rgrp);
.
## diffname port/sysproc.c 2002/0402
## diff -e /n/emeliedump/2002/0320/sys/src/9/port/sysproc.c /n/emeliedump/2002/0402/sys/src/9/port/sysproc.c
829,830d
7d
## diffname port/sysproc.c 2002/0404
## diff -e /n/emeliedump/2002/0402/sys/src/9/port/sysproc.c /n/emeliedump/2002/0404/sys/src/9/port/sysproc.c
827a
	if (isedf(up))
		edf_block(up);
.
6a
#include	"../port/edf.h"
.
## diffname port/sysproc.c 2002/0410
## diff -e /n/emeliedump/2002/0404/sys/src/9/port/sysproc.c /n/emeliedump/2002/0410/sys/src/9/port/sysproc.c
830c
		edfblock(up);
.
7d
## diffname port/sysproc.c 2002/0412
## diff -e /n/emeliedump/2002/0410/sys/src/9/port/sysproc.c /n/emeliedump/2002/0412/sys/src/9/port/sysproc.c
23a
*/
.
14a
	int x;
	long a;

	a = *arg;
	if(a > 0)
		return incref(&sysr1ref);
	if(a < 0)
		return decref(&sysr1ref);
	return sysr1ref.ref;

/*
.
11a
Ref sysr1ref;

.
## diffname port/sysproc.c 2002/0421
## diff -e /n/emeliedump/2002/0412/sys/src/9/port/sysproc.c /n/emeliedump/2002/0421/sys/src/9/port/sysproc.c
17d
## diffname port/sysproc.c 2002/0502
## diff -e /n/emeliedump/2002/0421/sys/src/9/port/sysproc.c /n/emeliedump/2002/0502/sys/src/9/port/sysproc.c
111a
	p->noswap = up->noswap;
.
## diffname port/sysproc.c 2002/0704
## diff -e /n/emeliedump/2002/0502/sys/src/9/port/sysproc.c /n/emeliedump/2002/0704/sys/src/9/port/sysproc.c
842,843c
	if (edf->isedf(up))
		edf->edfblock(up);
.
## diffname port/sysproc.c 2002/0816
## diff -e /n/emeliedump/2002/0704/sys/src/9/port/sysproc.c /n/emeliedump/2002/0816/sys/src/9/port/sysproc.c
493a
print("go\n");
.
434a
print("set up segments\n");
.
## diffname port/sysproc.c 2002/0817
## diff -e /n/emeliedump/2002/0816/sys/src/9/port/sysproc.c /n/emeliedump/2002/0817/sys/src/9/port/sysproc.c
495d
435c
print("set up segments for pid %lud\n", up->pid);
.
## diffname port/sysproc.c 2002/0819
## diff -e /n/emeliedump/2002/0817/sys/src/9/port/sysproc.c /n/emeliedump/2002/0819/sys/src/9/port/sysproc.c
435d
## diffname port/sysproc.c 2002/1222
## diff -e /n/emeliedump/2002/0819/sys/src/9/port/sysproc.c /n/emeliedump/2002/1222/sys/src/9/port/sysproc.c
18a
extern int devdebug;
devdebug = !devdebug;

.
## diffname port/sysproc.c 2003/0108
## diff -e /n/emeliedump/2002/1222/sys/src/9/port/sysproc.c /n/emeliedump/2003/0108/sys/src/9/port/sysproc.c
19,21d
## diffname port/sysproc.c 2003/0314
## diff -e /n/emeliedump/2003/0108/sys/src/9/port/sysproc.c /n/emeliedump/2003/0314/sys/src/9/port/sysproc.c
543,544c
		yield();
.
## diffname port/sysproc.c 2003/0406
## diff -e /n/emeliedump/2003/0314/sys/src/9/port/sysproc.c /n/emeliedump/2003/0406/sys/src/9/port/sysproc.c
841c
	if(edf->isedf(up))
.

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].