|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: * @(#)kern_proc.c 7.16 (Berkeley) 6/28/91
34: */
35:
36: #include "param.h"
37: #include "systm.h"
38: #include "map.h"
39: #include "kernel.h"
40: #include "proc.h"
41: #include "buf.h"
42: #include "seg.h"
43: #include "acct.h"
44: #include "wait.h"
45: #include "file.h"
46: #include "../ufs/quota.h"
47: #include "uio.h"
48: #include "malloc.h"
49: #include "mbuf.h"
50: #include "ioctl.h"
51: #include "tty.h"
52:
53: /*
54: * Is p an inferior of the current process?
55: */
56: inferior(p)
57: register struct proc *p;
58: {
59:
60: for (; p != curproc; p = p->p_pptr)
61: if (p->p_pid == 0)
62: return (0);
63: return (1);
64: }
65:
66: /*
67: * Locate a process by number
68: */
69: struct proc *
70: pfind(pid)
71: register pid;
72: {
73: register struct proc *p = pidhash[PIDHASH(pid)];
74:
75: for (; p; p = p->p_hash)
76: if (p->p_pid == pid)
77: return (p);
78: return ((struct proc *)0);
79: }
80:
81: /*
82: * Locate a process group by number
83: */
84: struct pgrp *
85: pgfind(pgid)
86: register pid_t pgid;
87: {
88: register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
89:
90: for (; pgrp; pgrp = pgrp->pg_hforw)
91: if (pgrp->pg_id == pgid)
92: return (pgrp);
93: return ((struct pgrp *)0);
94: }
95:
96: /*
97: * Move p to a new or existing process group (and session)
98: */
99: enterpgrp(p, pgid, mksess)
100: register struct proc *p;
101: pid_t pgid;
102: {
103: register struct pgrp *pgrp = pgfind(pgid);
104: register struct proc **pp;
105: register struct proc *cp;
106: int n;
107:
108: #ifdef DIAGNOSTIC
109: if (pgrp && mksess) /* firewalls */
110: panic("enterpgrp: setsid into non-empty pgrp");
111: if (SESS_LEADER(p))
112: panic("enterpgrp: session leader attempted setpgrp");
113: #endif
114: if (pgrp == NULL) {
115: /*
116: * new process group
117: */
118: #ifdef DIAGNOSTIC
119: if (p->p_pid != pgid)
120: panic("enterpgrp: new pgrp and pid != pgid");
121: #endif
122: MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
123: M_WAITOK);
124: if (mksess) {
125: register struct session *sess;
126:
127: /*
128: * new session
129: */
130: MALLOC(sess, struct session *, sizeof(struct session),
131: M_SESSION, M_WAITOK);
132: sess->s_leader = p;
133: sess->s_count = 1;
134: sess->s_ttyvp = NULL;
135: sess->s_ttyp = NULL;
136: bcopy(p->p_session->s_login, sess->s_login,
137: sizeof(sess->s_login));
138: p->p_flag &= ~SCTTY;
139: pgrp->pg_session = sess;
140: #ifdef DIAGNOSTIC
141: if (p != curproc)
142: panic("enterpgrp: mksession and p != curproc");
143: #endif
144: } else {
145: pgrp->pg_session = p->p_session;
146: pgrp->pg_session->s_count++;
147: }
148: pgrp->pg_id = pgid;
149: pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)];
150: pgrphash[n] = pgrp;
151: pgrp->pg_jobc = 0;
152: pgrp->pg_mem = NULL;
153: } else if (pgrp == p->p_pgrp)
154: return;
155:
156: /*
157: * Adjust eligibility of affected pgrps to participate in job control.
158: * Increment eligibility counts before decrementing, otherwise we
159: * could reach 0 spuriously during the first call.
160: */
161: fixjobc(p, pgrp, 1);
162: fixjobc(p, p->p_pgrp, 0);
163:
164: /*
165: * unlink p from old process group
166: */
167: for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt)
168: if (*pp == p) {
169: *pp = p->p_pgrpnxt;
170: goto done;
171: }
172: panic("enterpgrp: can't find p on old pgrp");
173: done:
174: /*
175: * delete old if empty
176: */
177: if (p->p_pgrp->pg_mem == 0)
178: pgdelete(p->p_pgrp);
179: /*
180: * link into new one
181: */
182: p->p_pgrp = pgrp;
183: p->p_pgrpnxt = pgrp->pg_mem;
184: pgrp->pg_mem = p;
185: }
186:
187: /*
188: * remove process from process group
189: */
190: leavepgrp(p)
191: register struct proc *p;
192: {
193: register struct proc **pp = &p->p_pgrp->pg_mem;
194:
195: for (; *pp; pp = &(*pp)->p_pgrpnxt)
196: if (*pp == p) {
197: *pp = p->p_pgrpnxt;
198: goto done;
199: }
200: panic("leavepgrp: can't find p in pgrp");
201: done:
202: if (!p->p_pgrp->pg_mem)
203: pgdelete(p->p_pgrp);
204: p->p_pgrp = 0;
205: }
206:
207: /*
208: * delete a process group
209: */
210: pgdelete(pgrp)
211: register struct pgrp *pgrp;
212: {
213: register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
214:
215: if (pgrp->pg_session->s_ttyp != NULL &&
216: pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
217: pgrp->pg_session->s_ttyp->t_pgrp = NULL;
218: for (; *pgp; pgp = &(*pgp)->pg_hforw)
219: if (*pgp == pgrp) {
220: *pgp = pgrp->pg_hforw;
221: goto done;
222: }
223: panic("pgdelete: can't find pgrp on hash chain");
224: done:
225: if (--pgrp->pg_session->s_count == 0)
226: FREE(pgrp->pg_session, M_SESSION);
227: FREE(pgrp, M_PGRP);
228: }
229:
230: static orphanpg();
231:
232: /*
233: * Adjust pgrp jobc counters when specified process changes process group.
234: * We count the number of processes in each process group that "qualify"
235: * the group for terminal job control (those with a parent in a different
236: * process group of the same session). If that count reaches zero, the
237: * process group becomes orphaned. Check both the specified process'
238: * process group and that of its children.
239: * entering == 0 => p is leaving specified group.
240: * entering == 1 => p is entering specified group.
241: */
242: fixjobc(p, pgrp, entering)
243: register struct proc *p;
244: register struct pgrp *pgrp;
245: int entering;
246: {
247: register struct pgrp *hispgrp;
248: register struct session *mysession = pgrp->pg_session;
249:
250: /*
251: * Check p's parent to see whether p qualifies its own process
252: * group; if so, adjust count for p's process group.
253: */
254: if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
255: hispgrp->pg_session == mysession)
256: if (entering)
257: pgrp->pg_jobc++;
258: else if (--pgrp->pg_jobc == 0)
259: orphanpg(pgrp);
260:
261: /*
262: * Check this process' children to see whether they qualify
263: * their process groups; if so, adjust counts for children's
264: * process groups.
265: */
266: for (p = p->p_cptr; p; p = p->p_osptr)
267: if ((hispgrp = p->p_pgrp) != pgrp &&
268: hispgrp->pg_session == mysession &&
269: p->p_stat != SZOMB)
270: if (entering)
271: hispgrp->pg_jobc++;
272: else if (--hispgrp->pg_jobc == 0)
273: orphanpg(hispgrp);
274: }
275:
276: /*
277: * A process group has become orphaned;
278: * if there are any stopped processes in the group,
279: * hang-up all process in that group.
280: */
281: static
282: orphanpg(pg)
283: struct pgrp *pg;
284: {
285: register struct proc *p;
286:
287: for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
288: if (p->p_stat == SSTOP) {
289: for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
290: psignal(p, SIGHUP);
291: psignal(p, SIGCONT);
292: }
293: return;
294: }
295: }
296: }
297:
298: #ifdef debug
299: /* DEBUG */
300: pgrpdump()
301: {
302: register struct pgrp *pgrp;
303: register struct proc *p;
304: register i;
305:
306: for (i=0; i<PIDHSZ; i++) {
307: if (pgrphash[i]) {
308: printf("\tindx %d\n", i);
309: for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
310: printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
311: pgrp, pgrp->pg_id, pgrp->pg_session,
312: pgrp->pg_session->s_count, pgrp->pg_mem);
313: for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
314: printf("\t\tpid %d addr %x pgrp %x\n",
315: p->p_pid, p, p->p_pgrp);
316: }
317: }
318:
319: }
320: }
321: }
322: #endif /* debug */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.