|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution is only permitted until one year after the first shipment
6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
7: * binary forms are permitted provided that: (1) source distributions retain
8: * this entire copyright notice and comment, and (2) distributions including
9: * binaries display the following acknowledgement: This product includes
10: * software developed by the University of California, Berkeley and its
11: * contributors'' in the documentation or other materials provided with the
12: * distribution and in all advertising materials mentioning features or use
13: * of this software. Neither the name of the University nor the names of
14: * its contributors may be used to endorse or promote products derived from
15: * this software without specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: *
20: * @(#)kern_proc.c 7.11 (Berkeley) 6/28/90
21: */
22:
23: #include "param.h"
24: #include "systm.h"
25: #include "map.h"
26: #include "user.h"
27: #include "kernel.h"
28: #include "proc.h"
29: #include "buf.h"
30: #include "seg.h"
31: #include "acct.h"
32: #include "wait.h"
33: #include "vm.h"
34: #include "text.h"
35: #include "file.h"
36: #include "../ufs/quota.h"
37: #include "uio.h"
38: #include "malloc.h"
39: #include "mbuf.h"
40: #include "ioctl.h"
41: #include "tty.h"
42:
43: #include "machine/reg.h"
44: #include "machine/pte.h"
45: #include "machine/psl.h"
46:
47: /*
48: * Is p an inferior of the current process?
49: */
50: inferior(p)
51: register struct proc *p;
52: {
53: for (; p != u.u_procp; p = p->p_pptr)
54: if (p->p_ppid == 0)
55: return (0);
56: return (1);
57: }
58:
59: /*
60: * Locate a process by number
61: */
62: struct proc *
63: pfind(pid)
64: register pid;
65: {
66: register struct proc *p = pidhash[PIDHASH(pid)];
67:
68: for (; p; p = p->p_hash)
69: if (p->p_pid == pid)
70: return (p);
71: return ((struct proc *)0);
72: }
73:
74: /*
75: * Locate a process group by number
76: */
77: struct pgrp *
78: pgfind(pgid)
79: register pid_t pgid;
80: {
81: register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
82:
83: for (; pgrp; pgrp = pgrp->pg_hforw)
84: if (pgrp->pg_id == pgid)
85: return (pgrp);
86: return ((struct pgrp *)0);
87: }
88:
89: /*
90: * Move p to a new or existing process group (and session)
91: */
92: pgmv(p, pgid, mksess)
93: register struct proc *p;
94: pid_t pgid;
95: {
96: register struct pgrp *pgrp = pgfind(pgid);
97: register struct proc **pp = &p->p_pgrp->pg_mem;
98: register struct proc *cp;
99: struct pgrp *opgrp;
100: register n;
101:
102: #ifdef DIAGNOSTIC
103: if (pgrp && mksess) /* firewalls */
104: panic("pgmv: setsid into non-empty pgrp");
105: if (SESS_LEADER(p))
106: panic("pgmv: session leader attempted setpgrp");
107: #endif
108: if (pgrp == NULL) {
109: /*
110: * new process group
111: */
112: #ifdef DIAGNOSTIC
113: if (p->p_pid != pgid)
114: panic("pgmv: new pgrp and pid != pgid");
115: #endif
116: MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
117: M_WAITOK);
118: if (mksess) {
119: register struct session *sess;
120: /*
121: * new session
122: */
123: MALLOC(sess, struct session *, sizeof(struct session),
124: M_SESSION, M_WAITOK);
125: sess->s_leader = p;
126: sess->s_count = 1;
127: sess->s_ttyvp = NULL;
128: sess->s_ttyp = NULL;
129: p->p_flag &= ~SCTTY;
130: pgrp->pg_session = sess;
131: #ifdef DIAGNOSTIC
132: if (p != u.u_procp)
133: panic("pgmv: mksession and p != u.u_procp");
134: #endif
135: } else {
136: pgrp->pg_session = p->p_session;
137: pgrp->pg_session->s_count++;
138: }
139: pgrp->pg_id = pgid;
140: pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)];
141: pgrphash[n] = pgrp;
142: pgrp->pg_jobc = 0;
143: pgrp->pg_mem = NULL;
144: } else if (pgrp == p->p_pgrp)
145: return;
146: /*
147: * adjust eligibility of affected pgrps to participate in job control
148: */
149: fixjobc(p, 0);
150: /*
151: * unlink p from old process group
152: */
153: for (; *pp; pp = &(*pp)->p_pgrpnxt)
154: if (*pp == p) {
155: *pp = p->p_pgrpnxt;
156: goto done;
157: }
158: panic("pgmv: can't find p on old pgrp");
159: done:
160: /*
161: * link into new one
162: */
163: p->p_pgrpnxt = pgrp->pg_mem;
164: pgrp->pg_mem = p;
165: opgrp = p->p_pgrp;
166: p->p_pgrp = pgrp;
167: /*
168: * adjust eligibility of affected pgrps to participate in job control
169: */
170: fixjobc(p, 1);
171: /*
172: * delete old if empty
173: */
174: if (!opgrp->pg_mem)
175: pgdelete(opgrp);
176: }
177:
178: /*
179: * remove process from process group
180: */
181: pgrm(p)
182: register struct proc *p;
183: {
184: register struct proc **pp = &p->p_pgrp->pg_mem;
185:
186: for (; *pp; pp = &(*pp)->p_pgrpnxt)
187: if (*pp == p) {
188: *pp = p->p_pgrpnxt;
189: goto done;
190: }
191: panic("pgrm: can't find p in pgrp");
192: done:
193: if (!p->p_pgrp->pg_mem)
194: pgdelete(p->p_pgrp);
195: p->p_pgrp = 0;
196: }
197:
198: /*
199: * delete a process group
200: */
201: pgdelete(pgrp)
202: register struct pgrp *pgrp;
203: {
204: register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
205:
206: if (pgrp->pg_session->s_ttyp != NULL &&
207: pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
208: pgrp->pg_session->s_ttyp->t_pgrp = NULL;
209: for (; *pgp; pgp = &(*pgp)->pg_hforw)
210: if (*pgp == pgrp) {
211: *pgp = pgrp->pg_hforw;
212: goto done;
213: }
214: panic("pgdelete: can't find pgrp on hash chain");
215: done:
216: if (--pgrp->pg_session->s_count == 0)
217: FREE(pgrp->pg_session, M_SESSION);
218: FREE(pgrp, M_PGRP);
219: }
220:
221: /*
222: * Adjust pgrp jobc counter.
223: * flag == 0 => p is leaving current state.
224: * flag == 1 => p is entering current state.
225: */
226: fixjobc(p, flag)
227: register struct proc *p;
228: register flag;
229: {
230: register struct pgrp *mypgrp = p->p_pgrp, *hispgrp;
231: register struct session *mysession = mypgrp->pg_session;
232: register struct proc *qp;
233:
234: if ((hispgrp = p->p_pptr->p_pgrp) != mypgrp &&
235: hispgrp->pg_session == mysession)
236: if (flag)
237: mypgrp->pg_jobc++;
238: else if (--mypgrp->pg_jobc == 0) {
239: int deliver = 0;
240:
241: sigstopped:
242: for (qp = mypgrp->pg_mem; qp != NULL;
243: qp = qp->p_pgrpnxt)
244: if (deliver) {
245: psignal(qp, SIGHUP);
246: psignal(qp, SIGCONT);
247: } else if (qp->p_stat == SSTOP) {
248: deliver++;
249: goto sigstopped;
250: }
251: }
252:
253: for (p = p->p_cptr; p != NULL; p = p->p_osptr)
254: if ((hispgrp = p->p_pgrp) != mypgrp &&
255: hispgrp->pg_session == mysession &&
256: p->p_stat != SZOMB)
257: if (flag)
258: hispgrp->pg_jobc++;
259: else if (--hispgrp->pg_jobc == 0) {
260: int deliver = 0;
261:
262: sigstopped2:
263: for (qp = hispgrp->pg_mem; qp != NULL;
264: qp = qp->p_pgrpnxt)
265: if (deliver) {
266: psignal(qp, SIGHUP);
267: psignal(qp, SIGCONT);
268: } else if (qp->p_stat == SSTOP) {
269: deliver++;
270: goto sigstopped2;
271: }
272: }
273: }
274:
275: /*
276: * init the process queues
277: */
278: pqinit()
279: {
280: register struct proc *p;
281:
282: /*
283: * most procs are initially on freequeue
284: * nb: we place them there in their "natural" order.
285: */
286:
287: freeproc = NULL;
288: for (p = procNPROC; --p > proc; freeproc = p)
289: p->p_nxt = freeproc;
290:
291: /*
292: * but proc[0] is special ...
293: */
294:
295: allproc = p;
296: p->p_nxt = NULL;
297: p->p_prev = &allproc;
298:
299: zombproc = NULL;
300: }
301:
302: #ifdef debug
303: /* DEBUG */
304: pgrpdump()
305: {
306: register struct pgrp *pgrp;
307: register struct proc *p;
308: register i;
309:
310: for (i=0; i<PIDHSZ; i++) {
311: if (pgrphash[i]) {
312: printf("\tindx %d\n", i);
313: for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
314: printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
315: pgrp, pgrp->pg_id, pgrp->pg_session,
316: pgrp->pg_session->s_count, pgrp->pg_mem);
317: for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
318: printf("\t\tpid %d addr %x pgrp %x\n",
319: p->p_pid, p, p->p_pgrp);
320: }
321: }
322:
323: }
324: }
325: }
326: #endif /* debug */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.