xref: /csrg-svn/sys/kern/kern_proc.c (revision 45673)
123371Smckusick /*
237728Smckusick  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
337728Smckusick  * All rights reserved.
423371Smckusick  *
544438Sbostic  * %sccs.include.redist.c%
637728Smckusick  *
7*45673Skarels  *	@(#)kern_proc.c	7.12 (Berkeley) 12/01/90
823371Smckusick  */
936Sbill 
1017091Sbloom #include "param.h"
1117091Sbloom #include "systm.h"
1217091Sbloom #include "map.h"
1317091Sbloom #include "user.h"
1417091Sbloom #include "kernel.h"
1517091Sbloom #include "proc.h"
1617091Sbloom #include "buf.h"
1717091Sbloom #include "seg.h"
1817091Sbloom #include "acct.h"
1917091Sbloom #include "wait.h"
2017091Sbloom #include "vm.h"
2117091Sbloom #include "text.h"
2217091Sbloom #include "file.h"
2337728Smckusick #include "../ufs/quota.h"
2417091Sbloom #include "uio.h"
2535810Smarc #include "malloc.h"
2617091Sbloom #include "mbuf.h"
2739064Smarc #include "ioctl.h"
2835810Smarc #include "tty.h"
2936Sbill 
3037524Smckusick #include "machine/reg.h"
3137524Smckusick #include "machine/pte.h"
3237524Smckusick #include "machine/psl.h"
3337524Smckusick 
3417540Skarels /*
357497Sroot  * Is p an inferior of the current process?
3636Sbill  */
377497Sroot inferior(p)
387816Sroot 	register struct proc *p;
3936Sbill {
40*45673Skarels 
417497Sroot 	for (; p != u.u_procp; p = p->p_pptr)
427497Sroot 		if (p->p_ppid == 0)
437497Sroot 			return (0);
447497Sroot 	return (1);
4536Sbill }
467816Sroot 
4740709Skarels /*
4840709Skarels  * Locate a process by number
4940709Skarels  */
507816Sroot struct proc *
517816Sroot pfind(pid)
5235810Smarc 	register pid;
537816Sroot {
5440709Skarels 	register struct proc *p = pidhash[PIDHASH(pid)];
557816Sroot 
5640709Skarels 	for (; p; p = p->p_hash)
577816Sroot 		if (p->p_pid == pid)
587816Sroot 			return (p);
597816Sroot 	return ((struct proc *)0);
607816Sroot }
6116529Skarels 
6216529Skarels /*
6335810Smarc  * Locate a process group by number
6435810Smarc  */
6535810Smarc struct pgrp *
6635810Smarc pgfind(pgid)
6735810Smarc 	register pid_t pgid;
6835810Smarc {
6935810Smarc 	register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
7035810Smarc 
7135810Smarc 	for (; pgrp; pgrp = pgrp->pg_hforw)
7235810Smarc 		if (pgrp->pg_id == pgid)
7340709Skarels 			return (pgrp);
7435810Smarc 	return ((struct pgrp *)0);
7535810Smarc }
7635810Smarc 
7735810Smarc /*
7835810Smarc  * Move p to a new or existing process group (and session)
7935810Smarc  */
8035810Smarc pgmv(p, pgid, mksess)
8135810Smarc 	register struct proc *p;
8235810Smarc 	pid_t pgid;
8335810Smarc {
8435810Smarc 	register struct pgrp *pgrp = pgfind(pgid);
85*45673Skarels 	register struct proc **pp;
8635810Smarc 	register struct proc *cp;
87*45673Skarels 	int n;
8835810Smarc 
8939562Smarc #ifdef DIAGNOSTIC
9035810Smarc 	if (pgrp && mksess)	/* firewalls */
9137589Smarc 		panic("pgmv: setsid into non-empty pgrp");
9235810Smarc 	if (SESS_LEADER(p))
9337589Smarc 		panic("pgmv: session leader attempted setpgrp");
9439562Smarc #endif
9537589Smarc 	if (pgrp == NULL) {
9635810Smarc 		/*
9735810Smarc 		 * new process group
9835810Smarc 		 */
9939562Smarc #ifdef DIAGNOSTIC
10035810Smarc 		if (p->p_pid != pgid)
10137589Smarc 			panic("pgmv: new pgrp and pid != pgid");
10239562Smarc #endif
10335810Smarc 		MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
10435810Smarc 		       M_WAITOK);
10535810Smarc 		if (mksess) {
10635810Smarc 			register struct session *sess;
10735810Smarc 			/*
10835810Smarc 			 * new session
10935810Smarc 			 */
11035810Smarc 			MALLOC(sess, struct session *, sizeof(struct session),
11135810Smarc 				M_SESSION, M_WAITOK);
11235810Smarc 			sess->s_leader = p;
11335810Smarc 			sess->s_count = 1;
11439562Smarc 			sess->s_ttyvp = NULL;
11539562Smarc 			sess->s_ttyp = NULL;
11639562Smarc 			p->p_flag &= ~SCTTY;
11735810Smarc 			pgrp->pg_session = sess;
11839562Smarc #ifdef DIAGNOSTIC
11935810Smarc 			if (p != u.u_procp)
12035810Smarc 				panic("pgmv: mksession and p != u.u_procp");
12139562Smarc #endif
12235810Smarc 		} else {
12335810Smarc 			pgrp->pg_session = p->p_session;
12435810Smarc 			pgrp->pg_session->s_count++;
12535810Smarc 		}
12635810Smarc 		pgrp->pg_id = pgid;
127*45673Skarels 		pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)];
12835810Smarc 		pgrphash[n] = pgrp;
12935810Smarc 		pgrp->pg_jobc = 0;
13039562Smarc 		pgrp->pg_mem = NULL;
13144387Smarc 	} else if (pgrp == p->p_pgrp)
13244387Smarc 		return;
133*45673Skarels 
13435810Smarc 	/*
135*45673Skarels 	 * Adjust eligibility of affected pgrps to participate in job control.
136*45673Skarels 	 * Increment eligibility counts before decrementing, otherwise we
137*45673Skarels 	 * could reach 0 spuriously during the first call.
13835810Smarc 	 */
139*45673Skarels 	fixjobc(p, pgrp, 1);
140*45673Skarels 	fixjobc(p, p->p_pgrp, 0);
141*45673Skarels 
14235810Smarc 	/*
14335810Smarc 	 * unlink p from old process group
14435810Smarc 	 */
145*45673Skarels 	for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt)
14635810Smarc 		if (*pp == p) {
14735810Smarc 			*pp = p->p_pgrpnxt;
14835810Smarc 			goto done;
14935810Smarc 		}
15037589Smarc 	panic("pgmv: can't find p on old pgrp");
15135810Smarc done:
15235810Smarc 	/*
153*45673Skarels 	 * delete old if empty
154*45673Skarels 	 */
155*45673Skarels 	if (p->p_pgrp->pg_mem == 0)
156*45673Skarels 		pgdelete(p->p_pgrp);
157*45673Skarels 	/*
15835810Smarc 	 * link into new one
15935810Smarc 	 */
160*45673Skarels 	p->p_pgrp = pgrp;
16135810Smarc 	p->p_pgrpnxt = pgrp->pg_mem;
16235810Smarc 	pgrp->pg_mem = p;
16335810Smarc }
16435810Smarc 
16535810Smarc /*
16635810Smarc  * remove process from process group
16735810Smarc  */
16835810Smarc pgrm(p)
16935810Smarc 	register struct proc *p;
17035810Smarc {
17135810Smarc 	register struct proc **pp = &p->p_pgrp->pg_mem;
17235810Smarc 
17335810Smarc 	for (; *pp; pp = &(*pp)->p_pgrpnxt)
17435810Smarc 		if (*pp == p) {
17535810Smarc 			*pp = p->p_pgrpnxt;
17635810Smarc 			goto done;
17735810Smarc 		}
17837589Smarc 	panic("pgrm: can't find p in pgrp");
17935810Smarc done:
18035810Smarc 	if (!p->p_pgrp->pg_mem)
18135810Smarc 		pgdelete(p->p_pgrp);
18235810Smarc 	p->p_pgrp = 0;
18335810Smarc }
18435810Smarc 
18535810Smarc /*
18635810Smarc  * delete a process group
18735810Smarc  */
18835810Smarc pgdelete(pgrp)
18935810Smarc 	register struct pgrp *pgrp;
19035810Smarc {
19135810Smarc 	register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
19235810Smarc 
19339562Smarc 	if (pgrp->pg_session->s_ttyp != NULL &&
19439562Smarc 	    pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
19539562Smarc 		pgrp->pg_session->s_ttyp->t_pgrp = NULL;
19635810Smarc 	for (; *pgp; pgp = &(*pgp)->pg_hforw)
19735810Smarc 		if (*pgp == pgrp) {
19835810Smarc 			*pgp = pgrp->pg_hforw;
19935810Smarc 			goto done;
20035810Smarc 		}
20137589Smarc 	panic("pgdelete: can't find pgrp on hash chain");
20235810Smarc done:
20335810Smarc 	if (--pgrp->pg_session->s_count == 0)
20435810Smarc 		FREE(pgrp->pg_session, M_SESSION);
20535810Smarc 	FREE(pgrp, M_PGRP);
20635810Smarc }
20735810Smarc 
20835810Smarc /*
209*45673Skarels  * Adjust pgrp jobc counters when specified process changes process group.
210*45673Skarels  * We count the number of processes in each process group that "qualify"
211*45673Skarels  * the group for terminal job control (those with a parent in a different
212*45673Skarels  * process group of the same session).  If that count reaches zero, the
213*45673Skarels  * process group becomes orphaned.  Check both the specified process'
214*45673Skarels  * process group and that of its children.
215*45673Skarels  * entering == 0 => p is leaving specified group.
216*45673Skarels  * entering == 1 => p is entering specified group.
21744387Smarc  */
218*45673Skarels fixjobc(p, pgrp, entering)
21944387Smarc 	register struct proc *p;
220*45673Skarels 	register struct pgrp *pgrp;
221*45673Skarels 	int entering;
22244387Smarc {
223*45673Skarels 	register struct pgrp *hispgrp;
224*45673Skarels 	register struct session *mysession = pgrp->pg_session;
22544387Smarc 
226*45673Skarels 	/*
227*45673Skarels 	 * Check p's parent to see whether p qualifies its own process
228*45673Skarels 	 * group; if so, adjust count for p's process group.
229*45673Skarels 	 */
230*45673Skarels 	if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
23144387Smarc 	    hispgrp->pg_session == mysession)
232*45673Skarels 		if (entering)
233*45673Skarels 			pgrp->pg_jobc++;
234*45673Skarels 		else if (--pgrp->pg_jobc == 0)
235*45673Skarels 			orphanpg(pgrp);
23644387Smarc 
237*45673Skarels 	/*
238*45673Skarels 	 * Check this process' children to see whether they qualify
239*45673Skarels 	 * their process groups; if so, adjust counts for children's
240*45673Skarels 	 * process groups.
241*45673Skarels 	 */
242*45673Skarels 	for (p = p->p_cptr; p; p = p->p_osptr)
243*45673Skarels 		if ((hispgrp = p->p_pgrp) != pgrp &&
24444387Smarc 		    hispgrp->pg_session == mysession &&
24544387Smarc 		    p->p_stat != SZOMB)
246*45673Skarels 			if (entering)
24744387Smarc 				hispgrp->pg_jobc++;
248*45673Skarels 			else if (--hispgrp->pg_jobc == 0)
249*45673Skarels 				orphanpg(hispgrp);
250*45673Skarels }
25144387Smarc 
252*45673Skarels /*
253*45673Skarels  * A process group has become orphaned;
254*45673Skarels  * if there are any stopped processes in the group,
255*45673Skarels  * hang-up all process in that group.
256*45673Skarels  */
257*45673Skarels static
258*45673Skarels orphanpg(pg)
259*45673Skarels 	struct pgrp *pg;
260*45673Skarels {
261*45673Skarels 	register struct proc *p;
262*45673Skarels 
263*45673Skarels 	for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
264*45673Skarels 		if (p->p_stat == SSTOP) {
265*45673Skarels 			for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
266*45673Skarels 				psignal(p, SIGHUP);
267*45673Skarels 				psignal(p, SIGCONT);
26844387Smarc 			}
269*45673Skarels 			return;
270*45673Skarels 		}
271*45673Skarels 	}
27244387Smarc }
273*45673Skarels 
27444387Smarc /*
27516529Skarels  * init the process queues
27616529Skarels  */
27716529Skarels pqinit()
27816529Skarels {
27916529Skarels 	register struct proc *p;
28016529Skarels 
28116529Skarels 	/*
28216529Skarels 	 * most procs are initially on freequeue
28316529Skarels 	 *	nb: we place them there in their "natural" order.
28416529Skarels 	 */
28516529Skarels 
28616529Skarels 	freeproc = NULL;
28716529Skarels 	for (p = procNPROC; --p > proc; freeproc = p)
28816529Skarels 		p->p_nxt = freeproc;
28916529Skarels 
29016529Skarels 	/*
29116529Skarels 	 * but proc[0] is special ...
29216529Skarels 	 */
29316529Skarels 
29416529Skarels 	allproc = p;
29516529Skarels 	p->p_nxt = NULL;
29616529Skarels 	p->p_prev = &allproc;
29716529Skarels 
29816529Skarels 	zombproc = NULL;
29916529Skarels }
30035810Smarc 
30137728Smckusick #ifdef debug
30235810Smarc /* DEBUG */
30335810Smarc pgrpdump()
30435810Smarc {
30535810Smarc 	register struct pgrp *pgrp;
30635810Smarc 	register struct proc *p;
30735810Smarc 	register i;
30835810Smarc 
30935810Smarc 	for (i=0; i<PIDHSZ; i++) {
31035810Smarc 		if (pgrphash[i]) {
31135810Smarc 		  printf("\tindx %d\n", i);
31235810Smarc 		  for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
31335810Smarc 		    printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
31435810Smarc 			pgrp, pgrp->pg_id, pgrp->pg_session,
31535810Smarc 			pgrp->pg_session->s_count, pgrp->pg_mem);
31635810Smarc 		    for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
31735810Smarc 			printf("\t\tpid %d addr %x pgrp %x\n",
31835810Smarc 				p->p_pid, p, p->p_pgrp);
31935810Smarc 		    }
32035810Smarc 		  }
32135810Smarc 
32235810Smarc 		}
32335810Smarc 	}
32435810Smarc }
32537728Smckusick #endif /* debug */
326