xref: /csrg-svn/sys/kern/kern_proc.c (revision 8816)
1 /*	kern_proc.c	4.44	82/10/22	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/map.h"
6 #include "../h/dir.h"
7 #include "../h/user.h"
8 #include "../h/kernel.h"
9 #include "../h/proc.h"
10 #include "../h/buf.h"
11 #include "../h/reg.h"
12 #include "../h/inode.h"
13 #include "../h/seg.h"
14 #include "../h/acct.h"
15 #include "/usr/include/wait.h"
16 #include "../h/pte.h"
17 #include "../h/vm.h"
18 #include "../h/text.h"
19 #include "../h/psl.h"
20 #include "../h/file.h"
21 #include "../h/quota.h"
22 #include "../h/descrip.h"
23 #include "../h/uio.h"
24 #include "../h/mbuf.h"
25 
26 gethostid()
27 {
28 
29 	u.u_r.r_val1 = hostid;
30 }
31 
32 sethostid()
33 {
34 	struct a {
35 		int	hostid;
36 	} *uap = (struct a *)u.u_ap;
37 
38 	if (suser())
39 		hostid = uap->hostid;
40 }
41 
42 gethostname()
43 {
44 	register struct a {
45 		char	*hostname;
46 		int	len;
47 	} *uap = (struct a *)u.u_ap;
48 	register u_int len;
49 
50 	len = uap->len;
51 	if (len > hostnamelen)
52 		len = hostnamelen;
53 	if (copyout((caddr_t)hostname, (caddr_t)uap->hostname, len))
54 		u.u_error = EFAULT;
55 }
56 
57 sethostname()
58 {
59 	register struct a {
60 		char	*hostname;
61 		u_int	len;
62 	} *uap = (struct a *)u.u_ap;
63 
64 	if (!suser())
65 		return;
66 	if (uap->len > sizeof (hostname) - 1) {
67 		u.u_error = EINVAL;
68 		return;
69 	}
70 	hostnamelen = uap->len;
71 	if (copyin((caddr_t)uap->hostname, hostname, uap->len))
72 		u.u_error = EFAULT;
73 	hostname[hostnamelen] = 0;
74 }
75 
76 /*
77  * exec system call, with and without environments.
78  */
79 struct execa {
80 	char	*fname;
81 	char	**argp;
82 	char	**envp;
83 };
84 
85 execv()
86 {
87 	((struct execa *)u.u_ap)->envp = NULL;
88 	execve();
89 }
90 
91 execve()
92 {
93 	register nc;
94 	register char *cp;
95 	register struct buf *bp;
96 	register struct execa *uap;
97 	int na, ne, ucp, ap, c;
98 	int indir, uid, gid;
99 	char *sharg;
100 	struct inode *ip;
101 	swblk_t bno;
102 	char cfname[MAXNAMLEN + 1];
103 	char cfarg[SHSIZE];
104 	int resid;
105 
106 	if ((ip = namei(uchar, 0, 1)) == NULL)
107 		return;
108 	bno = 0;
109 	bp = 0;
110 	indir = 0;
111 	uid = u.u_uid;
112 	gid = u.u_gid;
113 	if (ip->i_mode & ISUID)
114 		uid = ip->i_uid;
115 	if (ip->i_mode & ISGID)
116 		gid = ip->i_gid;
117 
118   again:
119 	if (access(ip, IEXEC))
120 		goto bad;
121 	if ((u.u_procp->p_flag&STRC) && access(ip, IREAD))
122 		goto bad;
123 	if ((ip->i_mode & IFMT) != IFREG ||
124 	   (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) {
125 		u.u_error = EACCES;
126 		goto bad;
127 	}
128 
129 	/*
130 	 * Read in first few bytes of file for segment sizes, ux_mag:
131 	 *	407 = plain executable
132 	 *	410 = RO text
133 	 *	413 = demand paged RO text
134 	 * Also an ASCII line beginning with #! is
135 	 * the file name of a ``shell'' and arguments may be prepended
136 	 * to the argument list if given here.
137 	 *
138 	 * SHELL NAMES ARE LIMITED IN LENGTH.
139 	 *
140 	 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
141 	 * THE ASCII LINE.
142 	 */
143 	u.u_error = rdwri(UIO_READ, ip, (caddr_t)&u.u_exdata, sizeof (u.u_exdata),
144 	    0, 1, &resid);
145 	if (u.u_error)
146 		goto bad;
147 	u.u_count = resid;
148 #ifndef lint
149 	if (u.u_count > sizeof(u.u_exdata) - sizeof(u.u_exdata.Ux_A) &&
150 	    u.u_exdata.ux_shell[0] != '#') {
151 		u.u_error = ENOEXEC;
152 		goto bad;
153 	}
154 #endif
155 	switch (u.u_exdata.ux_mag) {
156 
157 	case 0407:
158 		u.u_exdata.ux_dsize += u.u_exdata.ux_tsize;
159 		u.u_exdata.ux_tsize = 0;
160 		break;
161 
162 	case 0413:
163 	case 0410:
164 		if (u.u_exdata.ux_tsize == 0) {
165 			u.u_error = ENOEXEC;
166 			goto bad;
167 		}
168 		break;
169 
170 	default:
171 		if (u.u_exdata.ux_shell[0] != '#' ||
172 		    u.u_exdata.ux_shell[1] != '!' ||
173 		    indir) {
174 			u.u_error = ENOEXEC;
175 			goto bad;
176 		}
177 		cp = &u.u_exdata.ux_shell[2];		/* skip "#!" */
178 		while (cp < &u.u_exdata.ux_shell[SHSIZE]) {
179 			if (*cp == '\t')
180 				*cp = ' ';
181 			else if (*cp == '\n') {
182 				*cp = '\0';
183 				break;
184 			}
185 			cp++;
186 		}
187 		if (*cp != '\0') {
188 			u.u_error = ENOEXEC;
189 			goto bad;
190 		}
191 		cp = &u.u_exdata.ux_shell[2];
192 		while (*cp == ' ')
193 			cp++;
194 		u.u_dirp = cp;
195 		while (*cp && *cp != ' ')
196 			cp++;
197 		sharg = NULL;
198 		if (*cp) {
199 			*cp++ = '\0';
200 			while (*cp == ' ')
201 				cp++;
202 			if (*cp) {
203 				bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
204 				sharg = cfarg;
205 			}
206 		}
207 		bcopy((caddr_t)u.u_dent.d_name, (caddr_t)cfname,
208 		    (unsigned)(u.u_dent.d_namlen + 1));
209 		indir = 1;
210 		iput(ip);
211 		ip = namei(schar, 0, 1);
212 		if (ip == NULL)
213 			return;
214 		goto again;
215 	}
216 
217 	/*
218 	 * Collect arguments on "file" in swap space.
219 	 */
220 	na = 0;
221 	ne = 0;
222 	nc = 0;
223 	uap = (struct execa *)u.u_ap;
224 	if ((bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))))) == 0) {
225 		swkill(u.u_procp, "exece");
226 		goto bad;
227 	}
228 	if (bno % CLSIZE)
229 		panic("execa rmalloc");
230 	if (uap->argp) for (;;) {
231 		ap = NULL;
232 		if (indir && (na == 1 || na == 2 && sharg))
233 			ap = (int)uap->fname;
234 		else if (uap->argp) {
235 			ap = fuword((caddr_t)uap->argp);
236 			uap->argp++;
237 		}
238 		if (ap==NULL && uap->envp) {
239 			uap->argp = NULL;
240 			if ((ap = fuword((caddr_t)uap->envp)) == NULL)
241 				break;
242 			uap->envp++;
243 			ne++;
244 		}
245 		if (ap == NULL)
246 			break;
247 		na++;
248 		if (ap == -1)
249 			u.u_error = EFAULT;
250 		do {
251 			if (nc >= NCARGS-1)
252 				u.u_error = E2BIG;
253 			if (indir && na == 2 && sharg != NULL)
254 				c = *sharg++ & 0377;
255 			else if ((c = fubyte((caddr_t)ap++)) < 0)
256 				u.u_error = EFAULT;
257 			if (u.u_error) {
258 				if (bp)
259 					brelse(bp);
260 				bp = 0;
261 				goto badarg;
262 			}
263 			if (nc % (CLSIZE*NBPG) == 0) {
264 				if (bp)
265 					bdwrite(bp);
266 				bp = getblk(argdev, bno + nc / NBPG,
267 				    CLSIZE*NBPG);
268 				cp = bp->b_un.b_addr;
269 			}
270 			nc++;
271 			*cp++ = c;
272 		} while (c > 0);
273 	}
274 	if (bp)
275 		bdwrite(bp);
276 	bp = 0;
277 	nc = (nc + NBPW-1) & ~(NBPW-1);
278 	if (indir) {
279 		u.u_dent.d_namlen = strlen(cfname);
280 		bcopy((caddr_t)cfname, (caddr_t)u.u_dent.d_name,
281 		    (unsigned)(u.u_dent.d_namlen + 1));
282 	}
283 	getxfile(ip, nc + (na+4)*NBPW, uid, gid);
284 	if (u.u_error) {
285 badarg:
286 		for (c = 0; c < nc; c += CLSIZE*NBPG)
287 			if (bp = baddr(argdev, bno + c / NBPG, CLSIZE*NBPG)) {
288 				bp->b_flags |= B_AGE;		/* throw away */
289 				bp->b_flags &= ~B_DELWRI;	/* cancel io */
290 				brelse(bp);
291 				bp = 0;
292 			}
293 		goto bad;
294 	}
295 
296 	/*
297 	 * copy back arglist
298 	 */
299 	ucp = USRSTACK - nc - NBPW;
300 	ap = ucp - na*NBPW - 3*NBPW;
301 	u.u_ar0[SP] = ap;
302 	(void) suword((caddr_t)ap, na-ne);
303 	nc = 0;
304 	for (;;) {
305 		ap += NBPW;
306 		if (na==ne) {
307 			(void) suword((caddr_t)ap, 0);
308 			ap += NBPW;
309 		}
310 		if (--na < 0)
311 			break;
312 		(void) suword((caddr_t)ap, ucp);
313 		do {
314 			if (nc % (CLSIZE*NBPG) == 0) {
315 				if (bp)
316 					brelse(bp);
317 				bp = bread(argdev, bno + nc / NBPG,
318 				    CLSIZE*NBPG);
319 				bp->b_flags |= B_AGE;		/* throw away */
320 				bp->b_flags &= ~B_DELWRI;	/* cancel io */
321 				cp = bp->b_un.b_addr;
322 			}
323 			(void) subyte((caddr_t)ucp++, (c = *cp++));
324 			nc++;
325 		} while(c&0377);
326 	}
327 	(void) suword((caddr_t)ap, 0);
328 	(void) suword((caddr_t)ucp, 0);
329 	setregs();
330 bad:
331 	if (bp)
332 		brelse(bp);
333 	if (bno)
334 		rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno);
335 	iput(ip);
336 }
337 
338 /*
339  * Read in and set up memory for executed file.
340  */
341 getxfile(ip, nargc, uid, gid)
342 register struct inode *ip;
343 {
344 	register size_t ts, ds, ss;
345 	int pagi;
346 
347 	if (u.u_exdata.ux_mag == 0413)
348 		pagi = SPAGI;
349 	else
350 		pagi = 0;
351 	if (u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 &&
352 	    ip->i_count!=1) {
353 		register struct file *fp;
354 
355 		for (fp = file; fp < fileNFILE; fp++) {
356 			if (fp->f_type == DTYPE_FILE &&
357 			    fp->f_inode == ip && (fp->f_flag&FWRITE)) {
358 				u.u_error = ETXTBSY;
359 				goto bad;
360 			}
361 		}
362 	}
363 
364 	/*
365 	 * Compute text and data sizes and make sure not too large.
366 	 */
367 	ts = clrnd(btoc(u.u_exdata.ux_tsize));
368 	ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize)));
369 	ss = clrnd(SSIZE + btoc(nargc));
370 	if (chksize(ts, ds, ss))
371 		goto bad;
372 
373 	/*
374 	 * Make sure enough space to start process.
375 	 */
376 	u.u_cdmap = zdmap;
377 	u.u_csmap = zdmap;
378 	if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL)
379 		goto bad;
380 
381 	/*
382 	 * At this point, committed to the new image!
383 	 * Release virtual memory resources of old process, and
384 	 * initialize the virtual memory of the new process.
385 	 * If we resulted from vfork(), instead wakeup our
386 	 * parent who will set SVFDONE when he has taken back
387 	 * our resources.
388 	 */
389 	if ((u.u_procp->p_flag & SVFORK) == 0)
390 		vrelvm();
391 	else {
392 		u.u_procp->p_flag &= ~SVFORK;
393 		u.u_procp->p_flag |= SKEEP;
394 		wakeup((caddr_t)u.u_procp);
395 		while ((u.u_procp->p_flag & SVFDONE) == 0)
396 			sleep((caddr_t)u.u_procp, PZERO - 1);
397 		u.u_procp->p_flag &= ~(SVFDONE|SKEEP);
398 	}
399 	u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SNUSIG);
400 	u.u_procp->p_flag |= pagi;
401 	u.u_dmap = u.u_cdmap;
402 	u.u_smap = u.u_csmap;
403 	vgetvm(ts, ds, ss);
404 
405 	if (pagi == 0)
406 		u.u_error =
407 		    rdwri(UIO_READ, ip,
408 			(char*)ctob(ts), (int)u.u_exdata.ux_dsize,
409 			(int)(sizeof(u.u_exdata)+u.u_exdata.ux_tsize),
410 			0, (int *)0);
411 	xalloc(ip, pagi);
412 	if (pagi && u.u_procp->p_textp)
413 		vinifod((struct fpte *)dptopte(u.u_procp, 0),
414 		    PG_FTEXT, u.u_procp->p_textp->x_iptr,
415 		    (long)(1 + ts/CLSIZE), (int)btoc(u.u_exdata.ux_dsize));
416 
417 	/* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
418 #include "../vax/mtpr.h"		/* XXX */
419 	mtpr(TBIA, 0);
420 
421 	if (u.u_error)
422 		swkill(u.u_procp, "i/o error mapping pages");
423 	/*
424 	 * set SUID/SGID protections, if no tracing
425 	 */
426 	if ((u.u_procp->p_flag&STRC)==0) {
427 		u.u_uid = uid;
428 		u.u_procp->p_uid = uid;
429 		u.u_gid = gid;
430 		(void) entergroup(gid);
431 	} else
432 		psignal(u.u_procp, SIGTRAP);
433 	u.u_tsize = ts;
434 	u.u_dsize = ds;
435 	u.u_ssize = ss;
436 bad:
437 	return;
438 }
439 
440 /*
441  * Clear registers on exec
442  */
443 setregs()
444 {
445 	register int (**rp)();
446 	register i;
447 	long sigmask;
448 
449 	for (rp = &u.u_signal[1], sigmask = 1L; rp < &u.u_signal[NSIG];
450 	    sigmask <<= 1, rp++) {
451 		switch (*rp) {
452 
453 		case SIG_IGN:
454 		case SIG_DFL:
455 		case SIG_HOLD:
456 			continue;
457 
458 		default:
459 			/*
460 			 * Normal or deferring catch; revert to default.
461 			 */
462 			(void) spl6();
463 			*rp = SIG_DFL;
464 			if ((int)*rp & 1)
465 				u.u_procp->p_siga0 |= sigmask;
466 			else
467 				u.u_procp->p_siga0 &= ~sigmask;
468 			if ((int)*rp & 2)
469 				u.u_procp->p_siga1 |= sigmask;
470 			else
471 				u.u_procp->p_siga1 &= ~sigmask;
472 			(void) spl0();
473 			continue;
474 		}
475 	}
476 /*
477 	for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
478 		*rp++ = 0;
479 */
480 	u.u_ar0[PC] = u.u_exdata.ux_entloc + 2; /* skip over entry mask */
481 	for (i=0; i<NOFILE; i++) {
482 		if (u.u_pofile[i]&EXCLOSE) {
483 			closef(u.u_ofile[i], 1, u.u_pofile[i]);
484 			u.u_ofile[i] = NULL;
485 			u.u_pofile[i] = 0;
486 		}
487 	}
488 
489 	/*
490 	 * Remember file name for accounting.
491 	 */
492 	u.u_acflag &= ~AFORK;
493 	bcopy((caddr_t)u.u_dent.d_name, (caddr_t)u.u_comm,
494 	    (unsigned)(u.u_dent.d_namlen + 1));
495 }
496 
497 /*
498  * Exit system call: pass back caller's arg
499  */
500 rexit()
501 {
502 	register struct a {
503 		int	rval;
504 	} *uap;
505 
506 	uap = (struct a *)u.u_ap;
507 	exit((uap->rval & 0377) << 8);
508 }
509 
510 /*
511  * Release resources.
512  * Save u. area for parent to look at.
513  * Enter zombie state.
514  * Wake up parent and init processes,
515  * and dispose of children.
516  */
517 exit(rv)
518 {
519 	register int i;
520 	register struct proc *p, *q;
521 	register int x;
522 
523 #ifdef PGINPROF
524 	vmsizmon();
525 #endif
526 	p = u.u_procp;
527 	p->p_flag &= ~(STRC|SULOCK);
528 	p->p_flag |= SWEXIT;
529 	(void) spl6();
530 	if ((int)SIG_IGN & 1)
531 		p->p_siga0 = ~0;
532 	else
533 		p->p_siga0 = 0;
534 	if ((int)SIG_IGN & 2)
535 		p->p_siga1 = ~0;
536 	else
537 		p->p_siga1 = 0;
538 	(void) spl0();
539 	p->p_cpticks = 0;
540 	p->p_pctcpu = 0;
541 	for (i=0; i<NSIG; i++)
542 		u.u_signal[i] = SIG_IGN;
543 	untimeout(realitexpire, (caddr_t)p);
544 	/*
545 	 * Release virtual memory.  If we resulted from
546 	 * a vfork(), instead give the resources back to
547 	 * the parent.
548 	 */
549 	if ((p->p_flag & SVFORK) == 0)
550 		vrelvm();
551 	else {
552 		p->p_flag &= ~SVFORK;
553 		wakeup((caddr_t)p);
554 		while ((p->p_flag & SVFDONE) == 0)
555 			sleep((caddr_t)p, PZERO - 1);
556 		p->p_flag &= ~SVFDONE;
557 	}
558 	for (i = 0; i < NOFILE; i++) {
559 #ifdef notdef
560 		/* why was this like this? */
561 		f = u.u_ofile[i];
562 		u.u_ofile[i] = NULL;
563 		closef(f, 1);
564 #else
565 		closef(u.u_ofile[i], 1, u.u_pofile[i]);
566 		u.u_ofile[i] = NULL;
567 		u.u_pofile[i] = 0;
568 #endif
569 	}
570 	ilock(u.u_cdir);
571 	iput(u.u_cdir);
572 	if (u.u_rdir) {
573 		ilock(u.u_rdir);
574 		iput(u.u_rdir);
575 	}
576 	u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
577 	acct();
578 #ifdef QUOTA
579 	qclean();
580 #endif
581 	vrelpt(u.u_procp);
582 	vrelu(u.u_procp, 0);
583 	(void) spl5();		/* hack for mem alloc race XXX */
584 	multprog--;
585 	p->p_stat = SZOMB;
586 	noproc = 1;
587 	i = PIDHASH(p->p_pid);
588 	x = p - proc;
589 	if (pidhash[i] == x)
590 		pidhash[i] = p->p_idhash;
591 	else {
592 		for (i = pidhash[i]; i != 0; i = proc[i].p_idhash)
593 			if (proc[i].p_idhash == x) {
594 				proc[i].p_idhash = p->p_idhash;
595 				goto done;
596 			}
597 		panic("exit");
598 	}
599 	if (p->p_pid == 1)
600 		panic("init died");
601 done:
602 	p->p_xstat = rv;
603 	{ struct mbuf *m = m_getclr(M_DONTWAIT); p->p_ru = mtod(m, struct rusage *); }
604 	*p->p_ru = u.u_ru;
605 	ruadd(p->p_ru, &u.u_cru);
606 	for (q = proc; q < procNPROC; q++)
607 		if (q->p_pptr == p) {
608 			if (q->p_osptr)
609 				q->p_osptr->p_ysptr = q->p_ysptr;
610 			if (q->p_ysptr)
611 				q->p_ysptr->p_osptr = q->p_osptr;
612 			if (proc[1].p_cptr)
613 				proc[1].p_cptr->p_ysptr = q;
614 			q->p_osptr = proc[1].p_cptr;
615 			q->p_ysptr = NULL;
616 			proc[1].p_cptr = q;
617 
618 			q->p_pptr = &proc[1];
619 			q->p_ppid = 1;
620 			wakeup((caddr_t)&proc[1]);
621 			/*
622 			 * Traced processes are killed
623 			 * since their existence means someone is screwing up.
624 			 * Stopped processes are sent a hangup and a continue.
625 			 * This is designed to be ``safe'' for setuid
626 			 * processes since they must be willing to tolerate
627 			 * hangups anyways.
628 			 */
629 			if (q->p_flag&STRC) {
630 				q->p_flag &= ~STRC;
631 				psignal(q, SIGKILL);
632 			} else if (q->p_stat == SSTOP) {
633 				psignal(q, SIGHUP);
634 				psignal(q, SIGCONT);
635 			}
636 			/*
637 			 * Protect this process from future
638 			 * tty signals, clear TSTP/TTIN/TTOU if pending.
639 			 */
640 			(void) spgrp(q, -1);
641 		}
642 	psignal(p->p_pptr, SIGCHLD);
643 	wakeup((caddr_t)p->p_pptr);
644 	swtch();
645 }
646 
647 #include <vtimes.h>
648 
649 owait()
650 {
651 	struct rusage ru;
652 	struct vtimes *vtp, avt;
653 
654 	if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) {
655 		wait1(0, (struct rusage *)0);
656 		return;
657 	}
658 	vtp = (struct vtimes *)u.u_ar0[R1];
659 	wait1(u.u_ar0[R0], &ru);
660 	if (u.u_error)
661 		return;
662 	getvtimes(&ru, &avt);
663 	(void) copyout((caddr_t)&avt, (caddr_t)vtp, sizeof (struct vtimes));
664 }
665 
666 /*
667  * Wait system call.
668  * Search for a terminated (zombie) child,
669  * finally lay it to rest, and collect its status.
670  * Look also for stopped (traced) children,
671  * and pass back status from them.
672  */
673 wait1(options, ru)
674 	register int options;
675 	struct rusage *ru;
676 {
677 	register f;
678 	register struct proc *p, *q;
679 
680 	f = 0;
681 loop:
682 	for (p = proc; p < procNPROC; p++)
683 	if (p->p_pptr == u.u_procp) {
684 		f++;
685 		if (p->p_stat == SZOMB) {
686 			u.u_r.r_val1 = p->p_pid;
687 			u.u_r.r_val2 = p->p_xstat;
688 			p->p_xstat = 0;
689 			if (ru)
690 				*ru = *p->p_ru;
691 			ruadd(&u.u_cru, p->p_ru);
692 			(void) m_free(dtom(p->p_ru));
693 			p->p_ru = 0;
694 			p->p_stat = NULL;
695 			p->p_pid = 0;
696 			p->p_ppid = 0;
697 			if (q = p->p_ysptr)
698 				q->p_osptr = p->p_osptr;
699 			if (q = p->p_osptr)
700 				q->p_ysptr = p->p_ysptr;
701 			if ((q = p->p_pptr)->p_cptr == p)
702 				q->p_cptr = p->p_osptr;
703 			p->p_pptr = 0;
704 			p->p_ysptr = 0;
705 			p->p_osptr = 0;
706 			p->p_cptr = 0;
707 			p->p_sig = 0;
708 			p->p_siga0 = 0;
709 			p->p_siga1 = 0;
710 			p->p_pgrp = 0;
711 			p->p_flag = 0;
712 			p->p_wchan = 0;
713 			p->p_cursig = 0;
714 			return;
715 		}
716 		if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 &&
717 		    (p->p_flag&STRC || options&WUNTRACED)) {
718 			p->p_flag |= SWTED;
719 			u.u_r.r_val1 = p->p_pid;
720 			u.u_r.r_val2 = (p->p_cursig<<8) | WSTOPPED;
721 			return;
722 		}
723 	}
724 	if (f==0) {
725 		u.u_error = ECHILD;
726 		return;
727 	}
728 	if (options&WNOHANG) {
729 		u.u_r.r_val1 = 0;
730 		return;
731 	}
732 	if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) {
733 		u.u_eosys = RESTARTSYS;
734 		return;
735 	}
736 	sleep((caddr_t)u.u_procp, PWAIT);
737 	goto loop;
738 }
739 
740 /*
741  * fork system call.
742  */
743 fork()
744 {
745 
746 	u.u_cdmap = zdmap;
747 	u.u_csmap = zdmap;
748 	if (swpexpand(u.u_dsize, u.u_ssize, &u.u_cdmap, &u.u_csmap) == 0) {
749 		u.u_r.r_val2 = 0;
750 		return;
751 	}
752 	fork1(0);
753 }
754 
755 fork1(isvfork)
756 {
757 	register struct proc *p1, *p2;
758 #ifndef	QUOTA
759 	register a;
760 
761 	a = 0;
762 #else
763 	if (u.u_quota != NOQUOT && u.u_quota->q_plim &&
764 	    u.u_quota->q_cnt >= u.u_quota->q_plim) {
765 		u.u_error = EPROCLIM;
766 		return;
767 	}
768 #endif
769 	p2 = NULL;
770 	for (p1 = proc; p1 < procNPROC; p1++) {
771 #ifdef QUOTA
772 		if (p1->p_stat == NULL) {
773 			p2 = p1;
774 			break;
775 		}
776 #else
777 		if (p1->p_stat==NULL && p2==NULL)
778 			p2 = p1;
779 		else {
780 			if (p1->p_uid==u.u_uid && p1->p_stat!=NULL)
781 				a++;
782 		}
783 #endif
784 	}
785 	/*
786 	 * Disallow if
787 	 *  No processes at all;
788 	 *  not su and too many procs owned; or
789 	 *  not su and would take last slot.
790 	 */
791 	if (p2==NULL)
792 		tablefull("proc");
793 #ifdef QUOTA
794 	if (p2==NULL || (u.u_uid!=0 && p2==procNPROC-1)) {
795 #else
796 	if (p2==NULL || (u.u_uid!=0 && (p2==procNPROC-1 || a>MAXUPRC))) {
797 #endif
798 		u.u_error = EAGAIN;
799 		if (!isvfork) {
800 			(void) vsexpand(0, &u.u_cdmap, 1);
801 			(void) vsexpand(0, &u.u_csmap, 1);
802 		}
803 		goto out;
804 	}
805 	p1 = u.u_procp;
806 	if (newproc(isvfork)) {
807 		u.u_r.r_val1 = p1->p_pid;
808 		u.u_r.r_val2 = 1;  /* child */
809 		u.u_start = time.tv_sec;
810 		u.u_acflag = AFORK;
811 #ifdef QUOTA
812 		u.u_qflags &= ~QUF_LOGIN;
813 #endif
814 		return;
815 	}
816 	u.u_r.r_val1 = p2->p_pid;
817 
818 out:
819 	u.u_r.r_val2 = 0;
820 }
821 
822 spgrp(top, npgrp)
823 register struct proc *top;
824 {
825 	register struct proc *pp, *p;
826 	int f = 0;
827 
828 	for (p = top; npgrp == -1 || u.u_uid == p->p_uid ||
829 	    !u.u_uid || inferior(p); p = pp) {
830 		if (npgrp == -1) {
831 #define	bit(a)	(1<<(a-1))
832 			p->p_sig &= ~(bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
833 		} else
834 			p->p_pgrp = npgrp;
835 		f++;
836 		/*
837 		 * Search for children.
838 		 */
839 		for (pp = proc; pp < procNPROC; pp++)
840 			if (pp->p_pptr == p)
841 				goto cont;
842 		/*
843 		 * Search for siblings.
844 		 */
845 		for (; p != top; p = p->p_pptr)
846 			for (pp = p + 1; pp < procNPROC; pp++)
847 				if (pp->p_pptr == p->p_pptr)
848 					goto cont;
849 		break;
850 	cont:
851 		;
852 	}
853 	return (f);
854 }
855 
856 /*
857  * Is p an inferior of the current process?
858  */
859 inferior(p)
860 	register struct proc *p;
861 {
862 
863 	for (; p != u.u_procp; p = p->p_pptr)
864 		if (p->p_ppid == 0)
865 			return (0);
866 	return (1);
867 }
868 
869 struct proc *
870 pfind(pid)
871 	int pid;
872 {
873 	register struct proc *p;
874 
875 	for (p = &proc[pidhash[PIDHASH(pid)]]; p != &proc[0]; p = &proc[p->p_idhash])
876 		if (p->p_pid == pid)
877 			return (p);
878 	return ((struct proc *)0);
879 }
880 
881 /*
882  * Create a new process-- the internal version of
883  * sys fork.
884  * It returns 1 in the new process, 0 in the old.
885  */
886 newproc(isvfork)
887 	int isvfork;
888 {
889 	register struct proc *p;
890 	register struct proc *rpp, *rip;
891 	register int n;
892 	register struct file *fp;
893 
894 	p = NULL;
895 	/*
896 	 * First, just locate a slot for a process
897 	 * and copy the useful info from this process into it.
898 	 * The panic "cannot happen" because fork has already
899 	 * checked for the existence of a slot.
900 	 */
901 retry:
902 	mpid++;
903 	if (mpid >= 30000) {
904 		mpid = 0;
905 		goto retry;
906 	}
907 	for (rpp = proc; rpp < procNPROC; rpp++) {
908 		if (rpp->p_stat == NULL && p==NULL)
909 			p = rpp;
910 		if (rpp->p_pid==mpid || rpp->p_pgrp==mpid)
911 			goto retry;
912 	}
913 	if ((rpp = p) == NULL)
914 		panic("no procs");
915 
916 	/*
917 	 * Make a proc table entry for the new process.
918 	 */
919 	rip = u.u_procp;
920 #ifdef QUOTA
921 	(rpp->p_quota = rip->p_quota)->q_cnt++;
922 #endif
923 	rpp->p_stat = SIDL;
924 	timerclear(&rpp->p_realtimer.it_value);
925 	rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SNUSIG));
926 	if (isvfork) {
927 		rpp->p_flag |= SVFORK;
928 		rpp->p_ndx = rip->p_ndx;
929 	} else
930 		rpp->p_ndx = rpp - proc;
931 	rpp->p_uid = rip->p_uid;
932 	rpp->p_pgrp = rip->p_pgrp;
933 	rpp->p_nice = rip->p_nice;
934 	rpp->p_textp = isvfork ? 0 : rip->p_textp;
935 	rpp->p_pid = mpid;
936 	rpp->p_ppid = rip->p_pid;
937 	rpp->p_pptr = rip;
938 	rpp->p_osptr = rip->p_cptr;
939 	if (rip->p_cptr)
940 		rip->p_cptr->p_ysptr = rpp;
941 	rpp->p_ysptr = NULL;
942 	rpp->p_cptr = NULL;
943 	rip->p_cptr = rpp;
944 	rpp->p_time = 0;
945 	rpp->p_cpu = 0;
946 	rpp->p_siga0 = rip->p_siga0;
947 	rpp->p_siga1 = rip->p_siga1;
948 	/* take along any pending signals, like stops? */
949 	if (isvfork) {
950 		rpp->p_tsize = rpp->p_dsize = rpp->p_ssize = 0;
951 		rpp->p_szpt = clrnd(ctopt(UPAGES));
952 		forkstat.cntvfork++;
953 		forkstat.sizvfork += rip->p_dsize + rip->p_ssize;
954 	} else {
955 		rpp->p_tsize = rip->p_tsize;
956 		rpp->p_dsize = rip->p_dsize;
957 		rpp->p_ssize = rip->p_ssize;
958 		rpp->p_szpt = rip->p_szpt;
959 		forkstat.cntfork++;
960 		forkstat.sizfork += rip->p_dsize + rip->p_ssize;
961 	}
962 	rpp->p_rssize = 0;
963 	rpp->p_maxrss = rip->p_maxrss;
964 	rpp->p_wchan = 0;
965 	rpp->p_slptime = 0;
966 	rpp->p_pctcpu = 0;
967 	rpp->p_cpticks = 0;
968 	n = PIDHASH(rpp->p_pid);
969 	p->p_idhash = pidhash[n];
970 	pidhash[n] = rpp - proc;
971 	multprog++;
972 
973 	/*
974 	 * Increase reference counts on shared objects.
975 	 */
976 	for (n = 0; n < NOFILE; n++) {
977 		fp = u.u_ofile[n];
978 		if (fp == NULL)
979 			continue;
980 		fp->f_count++;
981 		if (u.u_pofile[n]&RDLOCK)
982 			fp->f_inode->i_rdlockc++;
983 		if (u.u_pofile[n]&WRLOCK)
984 			fp->f_inode->i_wrlockc++;
985 	}
986 	u.u_cdir->i_count++;
987 	if (u.u_rdir)
988 		u.u_rdir->i_count++;
989 
990 	/*
991 	 * Partially simulate the environment
992 	 * of the new process so that when it is actually
993 	 * created (by copying) it will look right.
994 	 * This begins the section where we must prevent the parent
995 	 * from being swapped.
996 	 */
997 	rip->p_flag |= SKEEP;
998 	if (procdup(rpp, isvfork))
999 		return (1);
1000 
1001 	/*
1002 	 * Make child runnable and add to run queue.
1003 	 */
1004 	(void) spl6();
1005 	rpp->p_stat = SRUN;
1006 	setrq(rpp);
1007 	(void) spl0();
1008 
1009 	/*
1010 	 * Cause child to take a non-local goto as soon as it runs.
1011 	 * On older systems this was done with SSWAP bit in proc
1012 	 * table; on VAX we use u.u_pcb.pcb_sswap so don't need
1013 	 * to do rpp->p_flag |= SSWAP.  Actually do nothing here.
1014 	 */
1015 	/* rpp->p_flag |= SSWAP; */
1016 
1017 	/*
1018 	 * Now can be swapped.
1019 	 */
1020 	rip->p_flag &= ~SKEEP;
1021 
1022 	/*
1023 	 * If vfork make chain from parent process to child
1024 	 * (where virtal memory is temporarily).  Wait for
1025 	 * child to finish, steal virtual memory back,
1026 	 * and wakeup child to let it die.
1027 	 */
1028 	if (isvfork) {
1029 		u.u_procp->p_xlink = rpp;
1030 		u.u_procp->p_flag |= SNOVM;
1031 		while (rpp->p_flag & SVFORK)
1032 			sleep((caddr_t)rpp, PZERO - 1);
1033 		if ((rpp->p_flag & SLOAD) == 0)
1034 			panic("newproc vfork");
1035 		uaccess(rpp, Vfmap, &vfutl);
1036 		u.u_procp->p_xlink = 0;
1037 		vpassvm(rpp, u.u_procp, &vfutl, &u, Vfmap);
1038 		u.u_procp->p_flag &= ~SNOVM;
1039 		rpp->p_ndx = rpp - proc;
1040 		rpp->p_flag |= SVFDONE;
1041 		wakeup((caddr_t)rpp);
1042 	}
1043 
1044 	/*
1045 	 * 0 return means parent.
1046 	 */
1047 	return (0);
1048 }
1049