|
|
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 "kernel.h"
39: #include "proc.h"
40: #include "buf.h"
41: #include "acct.h"
42: #include "wait.h"
43: #include "file.h"
44: #include "../ufs/quota.h"
45: #include "uio.h"
46: #include "malloc.h"
47: #include "mbuf.h"
48: #include "ioctl.h"
49: #include "tty.h"
50:
51: /*
52: * Is p an inferior of the current process?
53: */
54: inferior(p)
55: register struct proc *p;
56: {
57:
58: for (; p != curproc; p = p->p_pptr)
59: if (p->p_pid == 0)
60: return (0);
61: return (1);
62: }
63:
64: /*
65: * Locate a process by number
66: */
67: struct proc *
68: pfind(pid)
69: register pid;
70: {
71: register struct proc *p = pidhash[PIDHASH(pid)];
72:
73: for (; p; p = p->p_hash)
74: if (p->p_pid == pid)
75: return (p);
76: return ((struct proc *)0);
77: }
78:
79: /*
80: * Locate a process group by number
81: */
82: struct pgrp *
83: pgfind(pgid)
84: register pid_t pgid;
85: {
86: register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
87:
88: for (; pgrp; pgrp = pgrp->pg_hforw)
89: if (pgrp->pg_id == pgid)
90: return (pgrp);
91: return ((struct pgrp *)0);
92: }
93:
94: /*
95: * Move p to a new or existing process group (and session)
96: */
97: enterpgrp(p, pgid, mksess)
98: register struct proc *p;
99: pid_t pgid;
100: {
101: register struct pgrp *pgrp = pgfind(pgid);
102: register struct proc **pp;
103: register struct proc *cp;
104: int n;
105:
106: #ifdef DIAGNOSTIC
107: if (pgrp && mksess) /* firewalls */
108: panic("enterpgrp: setsid into non-empty pgrp");
109: if (SESS_LEADER(p))
110: panic("enterpgrp: session leader attempted setpgrp");
111: #endif
112: if (pgrp == NULL) {
113: /*
114: * new process group
115: */
116: #ifdef DIAGNOSTIC
117: if (p->p_pid != pgid)
118: panic("enterpgrp: new pgrp and pid != pgid");
119: #endif
120: MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
121: M_WAITOK);
122: if (mksess) {
123: register struct session *sess;
124:
125: /*
126: * new session
127: */
128: MALLOC(sess, struct session *, sizeof(struct session),
129: M_SESSION, M_WAITOK);
130: sess->s_leader = p;
131: sess->s_count = 1;
132: sess->s_ttyvp = NULL;
133: sess->s_ttyp = NULL;
134: bcopy(p->p_session->s_login, sess->s_login,
135: sizeof(sess->s_login));
136: p->p_flag &= ~SCTTY;
137: pgrp->pg_session = sess;
138: #ifdef DIAGNOSTIC
139: if (p != curproc)
140: panic("enterpgrp: mksession and p != curproc");
141: #endif
142: } else {
143: pgrp->pg_session = p->p_session;
144: pgrp->pg_session->s_count++;
145: }
146: pgrp->pg_id = pgid;
147: pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)];
148: pgrphash[n] = pgrp;
149: pgrp->pg_jobc = 0;
150: pgrp->pg_mem = NULL;
151: } else if (pgrp == p->p_pgrp)
152: return;
153:
154: /*
155: * Adjust eligibility of affected pgrps to participate in job control.
156: * Increment eligibility counts before decrementing, otherwise we
157: * could reach 0 spuriously during the first call.
158: */
159: fixjobc(p, pgrp, 1);
160: fixjobc(p, p->p_pgrp, 0);
161:
162: /*
163: * unlink p from old process group
164: */
165: for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt)
166: if (*pp == p) {
167: *pp = p->p_pgrpnxt;
168: goto done;
169: }
170: panic("enterpgrp: can't find p on old pgrp");
171: done:
172: /*
173: * delete old if empty
174: */
175: if (p->p_pgrp->pg_mem == 0)
176: pgdelete(p->p_pgrp);
177: /*
178: * link into new one
179: */
180: p->p_pgrp = pgrp;
181: p->p_pgrpnxt = pgrp->pg_mem;
182: pgrp->pg_mem = p;
183: }
184:
185: /*
186: * remove process from process group
187: */
188: leavepgrp(p)
189: register struct proc *p;
190: {
191: register struct proc **pp = &p->p_pgrp->pg_mem;
192:
193: for (; *pp; pp = &(*pp)->p_pgrpnxt)
194: if (*pp == p) {
195: *pp = p->p_pgrpnxt;
196: goto done;
197: }
198: panic("leavepgrp: can't find p in pgrp");
199: done:
200: if (!p->p_pgrp->pg_mem)
201: pgdelete(p->p_pgrp);
202: p->p_pgrp = 0;
203: }
204:
205: /*
206: * delete a process group
207: */
208: pgdelete(pgrp)
209: register struct pgrp *pgrp;
210: {
211: register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
212:
213: if (pgrp->pg_session->s_ttyp != NULL &&
214: pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
215: pgrp->pg_session->s_ttyp->t_pgrp = NULL;
216: for (; *pgp; pgp = &(*pgp)->pg_hforw)
217: if (*pgp == pgrp) {
218: *pgp = pgrp->pg_hforw;
219: goto done;
220: }
221: panic("pgdelete: can't find pgrp on hash chain");
222: done:
223: if (--pgrp->pg_session->s_count == 0)
224: FREE(pgrp->pg_session, M_SESSION);
225: FREE(pgrp, M_PGRP);
226: }
227:
228: static orphanpg();
229:
230: /*
231: * Adjust pgrp jobc counters when specified process changes process group.
232: * We count the number of processes in each process group that "qualify"
233: * the group for terminal job control (those with a parent in a different
234: * process group of the same session). If that count reaches zero, the
235: * process group becomes orphaned. Check both the specified process'
236: * process group and that of its children.
237: * entering == 0 => p is leaving specified group.
238: * entering == 1 => p is entering specified group.
239: */
240: fixjobc(p, pgrp, entering)
241: register struct proc *p;
242: register struct pgrp *pgrp;
243: int entering;
244: {
245: register struct pgrp *hispgrp;
246: register struct session *mysession = pgrp->pg_session;
247:
248: /*
249: * Check p's parent to see whether p qualifies its own process
250: * group; if so, adjust count for p's process group.
251: */
252: if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
253: hispgrp->pg_session == mysession)
254: if (entering)
255: pgrp->pg_jobc++;
256: else if (--pgrp->pg_jobc == 0)
257: orphanpg(pgrp);
258:
259: /*
260: * Check this process' children to see whether they qualify
261: * their process groups; if so, adjust counts for children's
262: * process groups.
263: */
264: for (p = p->p_cptr; p; p = p->p_osptr)
265: if ((hispgrp = p->p_pgrp) != pgrp &&
266: hispgrp->pg_session == mysession &&
267: p->p_stat != SZOMB)
268: if (entering)
269: hispgrp->pg_jobc++;
270: else if (--hispgrp->pg_jobc == 0)
271: orphanpg(hispgrp);
272: }
273:
274: /*
275: * A process group has become orphaned;
276: * if there are any stopped processes in the group,
277: * hang-up all process in that group.
278: */
279: static
280: orphanpg(pg)
281: struct pgrp *pg;
282: {
283: register struct proc *p;
284:
285: for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
286: if (p->p_stat == SSTOP) {
287: for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
288: psignal(p, SIGHUP);
289: psignal(p, SIGCONT);
290: }
291: return;
292: }
293: }
294: }
295:
296: #ifdef debug
297: /* DEBUG */
298: pgrpdump()
299: {
300: register struct pgrp *pgrp;
301: register struct proc *p;
302: register i;
303:
304: for (i=0; i<PIDHSZ; i++) {
305: if (pgrphash[i]) {
306: printf("\tindx %d\n", i);
307: for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
308: printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
309: pgrp, pgrp->pg_id, pgrp->pg_session,
310: pgrp->pg_session->s_count, pgrp->pg_mem);
311: for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
312: printf("\t\tpid %d addr %x pgrp %x\n",
313: p->p_pid, p, p->p_pgrp);
314: }
315: }
316:
317: }
318: }
319: }
320: #endif /* debug */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.