xref: /csrg-svn/sys/kern/kern_proc.c (revision 35810)
123371Smckusick /*
229091Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
323371Smckusick  * All rights reserved.  The Berkeley software License Agreement
423371Smckusick  * specifies the terms and conditions for redistribution.
523371Smckusick  *
6*35810Smarc  *	@(#)kern_proc.c	7.3 (Berkeley) 10/18/88
723371Smckusick  */
836Sbill 
99753Ssam #include "../machine/reg.h"
109753Ssam #include "../machine/pte.h"
119753Ssam #include "../machine/psl.h"
129753Ssam 
1317091Sbloom #include "param.h"
1417091Sbloom #include "systm.h"
1517091Sbloom #include "map.h"
1617091Sbloom #include "dir.h"
1717091Sbloom #include "user.h"
1817091Sbloom #include "kernel.h"
1917091Sbloom #include "proc.h"
2017091Sbloom #include "buf.h"
2117091Sbloom #include "seg.h"
2217091Sbloom #include "acct.h"
2317091Sbloom #include "wait.h"
2417091Sbloom #include "vm.h"
2517091Sbloom #include "text.h"
2617091Sbloom #include "file.h"
2717091Sbloom #include "quota.h"
2817091Sbloom #include "uio.h"
29*35810Smarc #include "malloc.h"
3017091Sbloom #include "mbuf.h"
31*35810Smarc #include "tty.h"
3236Sbill 
3317540Skarels /*
3425385Skarels  * Clear any pending stops for top and all descendents.
3517540Skarels  */
3625385Skarels spgrp(top)
3717540Skarels 	struct proc *top;
387497Sroot {
3917540Skarels 	register struct proc *p;
407497Sroot 	int f = 0;
417497Sroot 
4217540Skarels 	p = top;
4317540Skarels 	for (;;) {
4425385Skarels 		p->p_sig &=
4517540Skarels 			  ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU));
467497Sroot 		f++;
477497Sroot 		/*
4817540Skarels 		 * If this process has children, descend to them next,
4917540Skarels 		 * otherwise do any siblings, and if done with this level,
5017540Skarels 		 * follow back up the tree (but not past top).
517497Sroot 		 */
5217540Skarels 		if (p->p_cptr)
5317540Skarels 			p = p->p_cptr;
5417540Skarels 		else if (p == top)
5517540Skarels 			return (f);
5617540Skarels 		else if (p->p_osptr)
5717540Skarels 			p = p->p_osptr;
5817540Skarels 		else for (;;) {
5917540Skarels 			p = p->p_pptr;
6017540Skarels 			if (p == top)
6117540Skarels 				return (f);
6217540Skarels 			if (p->p_osptr) {
6317540Skarels 				p = p->p_osptr;
6417540Skarels 				break;
6517540Skarels 			}
6617540Skarels 		}
677497Sroot 	}
687497Sroot }
697497Sroot 
7036Sbill /*
717497Sroot  * Is p an inferior of the current process?
7236Sbill  */
737497Sroot inferior(p)
747816Sroot 	register struct proc *p;
7536Sbill {
767497Sroot 	for (; p != u.u_procp; p = p->p_pptr)
777497Sroot 		if (p->p_ppid == 0)
787497Sroot 			return (0);
797497Sroot 	return (1);
8036Sbill }
817816Sroot 
827816Sroot struct proc *
837816Sroot pfind(pid)
84*35810Smarc 	register pid;
857816Sroot {
867816Sroot 	register struct proc *p;
877816Sroot 
88*35810Smarc 	for (p = &proc[pidhash[PIDHASH(pid)]] ;
89*35810Smarc 	     p != &proc[0]; p = &proc[p->p_idhash])
907816Sroot 		if (p->p_pid == pid)
917816Sroot 			return (p);
927816Sroot 	return ((struct proc *)0);
937816Sroot }
9416529Skarels 
9516529Skarels /*
96*35810Smarc  * Locate a process group by number
97*35810Smarc  */
98*35810Smarc struct pgrp *
99*35810Smarc pgfind(pgid)
100*35810Smarc 	register pid_t pgid;
101*35810Smarc {
102*35810Smarc 	register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
103*35810Smarc 
104*35810Smarc 	for (; pgrp; pgrp = pgrp->pg_hforw)
105*35810Smarc 		if (pgrp->pg_id == pgid)
106*35810Smarc 			return(pgrp);
107*35810Smarc 	return ((struct pgrp *)0);
108*35810Smarc }
109*35810Smarc 
110*35810Smarc /*
111*35810Smarc  * Move p to a new or existing process group (and session)
112*35810Smarc  */
113*35810Smarc pgmv(p, pgid, mksess)
114*35810Smarc 	register struct proc *p;
115*35810Smarc 	pid_t pgid;
116*35810Smarc {
117*35810Smarc 	register struct pgrp *pgrp = pgfind(pgid);
118*35810Smarc 	register struct proc **pp = &p->p_pgrp->pg_mem;
119*35810Smarc 	register struct proc *cp;
120*35810Smarc 	register n;
121*35810Smarc 
122*35810Smarc 	if (pgrp && mksess)	/* firewalls */
123*35810Smarc 		panic("pgmv: setsid into non-empty pgrp %d\n", pgid);
124*35810Smarc 	if (SESS_LEADER(p))
125*35810Smarc 		panic("pgmv: session leader attempted setpgrp\n");
126*35810Smarc 	if (!pgrp) {
127*35810Smarc 		/*
128*35810Smarc 		 * new process group
129*35810Smarc 		 */
130*35810Smarc 		if (p->p_pid != pgid)
131*35810Smarc 			panic("pgmv: new pgrp and pid != pgid\n");
132*35810Smarc 		MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
133*35810Smarc 		       M_WAITOK);
134*35810Smarc 		if (mksess) {
135*35810Smarc 			register struct session *sess;
136*35810Smarc 			/*
137*35810Smarc 			 * new session
138*35810Smarc 			 */
139*35810Smarc 			MALLOC(sess, struct session *, sizeof(struct session),
140*35810Smarc 				M_SESSION, M_WAITOK);
141*35810Smarc 			sess->s_leader = p;
142*35810Smarc 			sess->s_count = 1;
143*35810Smarc 			pgrp->pg_session = sess;
144*35810Smarc 			if (p != u.u_procp)
145*35810Smarc 				panic("pgmv: mksession and p != u.u_procp");
146*35810Smarc 			u.u_ttyp = 0;
147*35810Smarc 			u.u_ttyd = 0;
148*35810Smarc 		} else {
149*35810Smarc 			pgrp->pg_session = p->p_session;
150*35810Smarc 			pgrp->pg_session->s_count++;
151*35810Smarc 		}
152*35810Smarc 		pgrp->pg_id = pgid;
153*35810Smarc 		pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)];
154*35810Smarc 		pgrphash[n] = pgrp;
155*35810Smarc 		pgrp->pg_jobc = 0;
156*35810Smarc 		pgrp->pg_mem = 0;
157*35810Smarc 	}
158*35810Smarc 	/*
159*35810Smarc 	 * adjust eligibility of affected pgrps to participate in job control
160*35810Smarc 	 */
161*35810Smarc 	if (PGRP_JOBC(p))
162*35810Smarc 		p->p_pgrp->pg_jobc--;
163*35810Smarc 	for (cp = p->p_cptr; cp; cp = cp->p_osptr)
164*35810Smarc 		if (PGRP_JOBC(cp))
165*35810Smarc 			cp->p_pgrp->pg_jobc--;
166*35810Smarc 	/*
167*35810Smarc 	 * unlink p from old process group
168*35810Smarc 	 */
169*35810Smarc 	for (; *pp; pp = &(*pp)->p_pgrpnxt)
170*35810Smarc 		if (*pp == p) {
171*35810Smarc 			*pp = p->p_pgrpnxt;
172*35810Smarc 			goto done;
173*35810Smarc 		}
174*35810Smarc 	panic("pgmv: can't find p on old pgrp\n");
175*35810Smarc done:
176*35810Smarc 	/*
177*35810Smarc 	 * link into new one
178*35810Smarc 	 */
179*35810Smarc 	p->p_pgrpnxt = pgrp->pg_mem;
180*35810Smarc 	pgrp->pg_mem = p;
181*35810Smarc 	p->p_pgrp = pgrp;
182*35810Smarc 	/*
183*35810Smarc 	 * adjust eligibility of affected pgrps to participate in job control
184*35810Smarc 	 */
185*35810Smarc 	if (PGRP_JOBC(p))
186*35810Smarc 		p->p_pgrp->pg_jobc++;
187*35810Smarc 	for (cp = p->p_cptr; cp; cp = cp->p_osptr)
188*35810Smarc 		if (PGRP_JOBC(cp))
189*35810Smarc 			cp->p_pgrp->pg_jobc++;
190*35810Smarc 	/*
191*35810Smarc 	 * old pgrp empty?
192*35810Smarc 	 */
193*35810Smarc 	if (!p->p_pgrp->pg_mem)
194*35810Smarc 		pgdelete(p->p_pgrp);
195*35810Smarc }
196*35810Smarc 
197*35810Smarc /*
198*35810Smarc  * remove process from process group
199*35810Smarc  */
200*35810Smarc pgrm(p)
201*35810Smarc 	register struct proc *p;
202*35810Smarc {
203*35810Smarc 	register struct proc **pp = &p->p_pgrp->pg_mem;
204*35810Smarc 	register struct proc *cp;
205*35810Smarc 
206*35810Smarc 	for (; *pp; pp = &(*pp)->p_pgrpnxt)
207*35810Smarc 		if (*pp == p) {
208*35810Smarc 			*pp = p->p_pgrpnxt;
209*35810Smarc 			goto done;
210*35810Smarc 		}
211*35810Smarc 	panic("pgrm: can't find p in pgrp\n");
212*35810Smarc done:
213*35810Smarc 	if (!p->p_pgrp->pg_mem)
214*35810Smarc 		pgdelete(p->p_pgrp);
215*35810Smarc 	p->p_pgrp = 0;
216*35810Smarc }
217*35810Smarc 
218*35810Smarc /*
219*35810Smarc  * delete a process group
220*35810Smarc  */
221*35810Smarc pgdelete(pgrp)
222*35810Smarc 	register struct pgrp *pgrp;
223*35810Smarc {
224*35810Smarc 	register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
225*35810Smarc 
226*35810Smarc 	for (; *pgp; pgp = &(*pgp)->pg_hforw)
227*35810Smarc 		if (*pgp == pgrp) {
228*35810Smarc 			*pgp = pgrp->pg_hforw;
229*35810Smarc 			goto done;
230*35810Smarc 		}
231*35810Smarc 	panic("pgdelete: can't find pgrp on hash chain\n");
232*35810Smarc done:
233*35810Smarc 	if (--pgrp->pg_session->s_count == 0)
234*35810Smarc 		FREE(pgrp->pg_session, M_SESSION);
235*35810Smarc 	FREE(pgrp, M_PGRP);
236*35810Smarc }
237*35810Smarc 
238*35810Smarc /*
23916529Skarels  * init the process queues
24016529Skarels  */
24116529Skarels pqinit()
24216529Skarels {
24316529Skarels 	register struct proc *p;
24416529Skarels 
24516529Skarels 	/*
24616529Skarels 	 * most procs are initially on freequeue
24716529Skarels 	 *	nb: we place them there in their "natural" order.
24816529Skarels 	 */
24916529Skarels 
25016529Skarels 	freeproc = NULL;
25116529Skarels 	for (p = procNPROC; --p > proc; freeproc = p)
25216529Skarels 		p->p_nxt = freeproc;
25316529Skarels 
25416529Skarels 	/*
25516529Skarels 	 * but proc[0] is special ...
25616529Skarels 	 */
25716529Skarels 
25816529Skarels 	allproc = p;
25916529Skarels 	p->p_nxt = NULL;
26016529Skarels 	p->p_prev = &allproc;
26116529Skarels 
26216529Skarels 	zombproc = NULL;
26316529Skarels }
264*35810Smarc 
265*35810Smarc /* DEBUG */
266*35810Smarc pgrpdump()
267*35810Smarc {
268*35810Smarc 	register struct pgrp *pgrp;
269*35810Smarc 	register struct proc *p;
270*35810Smarc 	register i;
271*35810Smarc 
272*35810Smarc 	for (i=0; i<PIDHSZ; i++) {
273*35810Smarc 		if (pgrphash[i]) {
274*35810Smarc 		  printf("\tindx %d\n", i);
275*35810Smarc 		  for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
276*35810Smarc 		    printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
277*35810Smarc 			pgrp, pgrp->pg_id, pgrp->pg_session,
278*35810Smarc 			pgrp->pg_session->s_count, pgrp->pg_mem);
279*35810Smarc 		    for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
280*35810Smarc 			printf("\t\tpid %d addr %x pgrp %x\n",
281*35810Smarc 				p->p_pid, p, p->p_pgrp);
282*35810Smarc 		    }
283*35810Smarc 		  }
284*35810Smarc 
285*35810Smarc 		}
286*35810Smarc 	}
287*35810Smarc }
288