get rid of extraneous header files
[unix-history] / usr / src / sys / kern / kern_proc.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
2e8f8cae 6 * @(#)kern_proc.c 7.3 (Berkeley) 10/18/88
da7c5cc6 7 */
961945a8 8
94368568
JB
9#include "param.h"
10#include "systm.h"
11#include "map.h"
12#include "dir.h"
13#include "user.h"
14#include "kernel.h"
15#include "proc.h"
16#include "buf.h"
94368568
JB
17#include "seg.h"
18#include "acct.h"
19#include "wait.h"
20#include "vm.h"
21#include "text.h"
22#include "file.h"
23#include "quota.h"
24#include "uio.h"
8fe87cbb 25#include "malloc.h"
94368568 26#include "mbuf.h"
8fe87cbb 27#include "tty.h"
a1bce776 28
d301d150
KM
29#include "machine/reg.h"
30#include "machine/pte.h"
31#include "machine/psl.h"
32
bdf8c113 33/*
f6ab5a0c 34 * Clear any pending stops for top and all descendents.
bdf8c113 35 */
f6ab5a0c 36spgrp(top)
bdf8c113 37 struct proc *top;
4147b3f6 38{
bdf8c113 39 register struct proc *p;
4147b3f6
BJ
40 int f = 0;
41
bdf8c113
MK
42 p = top;
43 for (;;) {
f6ab5a0c 44 p->p_sig &=
bdf8c113 45 ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU));
4147b3f6
BJ
46 f++;
47 /*
bdf8c113
MK
48 * If this process has children, descend to them next,
49 * otherwise do any siblings, and if done with this level,
50 * follow back up the tree (but not past top).
4147b3f6 51 */
bdf8c113
MK
52 if (p->p_cptr)
53 p = p->p_cptr;
54 else if (p == top)
55 return (f);
56 else if (p->p_osptr)
57 p = p->p_osptr;
58 else for (;;) {
59 p = p->p_pptr;
60 if (p == top)
61 return (f);
bdf8c113
MK
62 if (p->p_osptr) {
63 p = p->p_osptr;
64 break;
65 }
66 }
4147b3f6 67 }
4147b3f6
BJ
68}
69
29dd101b 70/*
4147b3f6 71 * Is p an inferior of the current process?
29dd101b 72 */
4147b3f6 73inferior(p)
a2a2a0d6 74 register struct proc *p;
29dd101b 75{
4147b3f6
BJ
76 for (; p != u.u_procp; p = p->p_pptr)
77 if (p->p_ppid == 0)
78 return (0);
79 return (1);
29dd101b 80}
a2a2a0d6
BJ
81
82struct proc *
83pfind(pid)
8fe87cbb 84 register pid;
a2a2a0d6
BJ
85{
86 register struct proc *p;
87
8fe87cbb
MT
88 for (p = &proc[pidhash[PIDHASH(pid)]] ;
89 p != &proc[0]; p = &proc[p->p_idhash])
a2a2a0d6
BJ
90 if (p->p_pid == pid)
91 return (p);
92 return ((struct proc *)0);
93}
1d348849 94
8fe87cbb
MT
95/*
96 * Locate a process group by number
97 */
98struct pgrp *
99pgfind(pgid)
100 register pid_t pgid;
101{
102 register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
103
104 for (; pgrp; pgrp = pgrp->pg_hforw)
105 if (pgrp->pg_id == pgid)
106 return(pgrp);
107 return ((struct pgrp *)0);
108}
109
110/*
111 * Move p to a new or existing process group (and session)
112 */
113pgmv(p, pgid, mksess)
114 register struct proc *p;
115 pid_t pgid;
116{
117 register struct pgrp *pgrp = pgfind(pgid);
118 register struct proc **pp = &p->p_pgrp->pg_mem;
119 register struct proc *cp;
2e8f8cae 120 struct pgrp *opgrp;
8fe87cbb
MT
121 register n;
122
123 if (pgrp && mksess) /* firewalls */
2e8f8cae 124 panic("pgmv: setsid into non-empty pgrp");
8fe87cbb 125 if (SESS_LEADER(p))
2e8f8cae
MT
126 panic("pgmv: session leader attempted setpgrp");
127 if (pgrp == NULL) {
8fe87cbb
MT
128 /*
129 * new process group
130 */
131 if (p->p_pid != pgid)
2e8f8cae 132 panic("pgmv: new pgrp and pid != pgid");
8fe87cbb
MT
133 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
134 M_WAITOK);
135 if (mksess) {
136 register struct session *sess;
137 /*
138 * new session
139 */
140 MALLOC(sess, struct session *, sizeof(struct session),
141 M_SESSION, M_WAITOK);
142 sess->s_leader = p;
143 sess->s_count = 1;
144 pgrp->pg_session = sess;
145 if (p != u.u_procp)
146 panic("pgmv: mksession and p != u.u_procp");
2e8f8cae 147 u.u_ttyp = NULL;
8fe87cbb
MT
148 u.u_ttyd = 0;
149 } else {
150 pgrp->pg_session = p->p_session;
151 pgrp->pg_session->s_count++;
152 }
153 pgrp->pg_id = pgid;
154 pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)];
155 pgrphash[n] = pgrp;
156 pgrp->pg_jobc = 0;
157 pgrp->pg_mem = 0;
158 }
159 /*
160 * adjust eligibility of affected pgrps to participate in job control
161 */
162 if (PGRP_JOBC(p))
163 p->p_pgrp->pg_jobc--;
164 for (cp = p->p_cptr; cp; cp = cp->p_osptr)
165 if (PGRP_JOBC(cp))
166 cp->p_pgrp->pg_jobc--;
167 /*
168 * unlink p from old process group
169 */
170 for (; *pp; pp = &(*pp)->p_pgrpnxt)
171 if (*pp == p) {
172 *pp = p->p_pgrpnxt;
173 goto done;
174 }
2e8f8cae 175 panic("pgmv: can't find p on old pgrp");
8fe87cbb
MT
176done:
177 /*
178 * link into new one
179 */
180 p->p_pgrpnxt = pgrp->pg_mem;
181 pgrp->pg_mem = p;
2e8f8cae 182 opgrp = p->p_pgrp;
8fe87cbb
MT
183 p->p_pgrp = pgrp;
184 /*
185 * adjust eligibility of affected pgrps to participate in job control
186 */
187 if (PGRP_JOBC(p))
188 p->p_pgrp->pg_jobc++;
189 for (cp = p->p_cptr; cp; cp = cp->p_osptr)
190 if (PGRP_JOBC(cp))
191 cp->p_pgrp->pg_jobc++;
192 /*
193 * old pgrp empty?
194 */
2e8f8cae
MT
195 if (!opgrp->pg_mem)
196 pgdelete(opgrp);
8fe87cbb
MT
197}
198
199/*
200 * remove process from process group
201 */
202pgrm(p)
203 register struct proc *p;
204{
205 register struct proc **pp = &p->p_pgrp->pg_mem;
206 register struct proc *cp;
207
208 for (; *pp; pp = &(*pp)->p_pgrpnxt)
209 if (*pp == p) {
210 *pp = p->p_pgrpnxt;
211 goto done;
212 }
2e8f8cae 213 panic("pgrm: can't find p in pgrp");
8fe87cbb
MT
214done:
215 if (!p->p_pgrp->pg_mem)
216 pgdelete(p->p_pgrp);
217 p->p_pgrp = 0;
218}
219
220/*
221 * delete a process group
222 */
223pgdelete(pgrp)
224 register struct pgrp *pgrp;
225{
226 register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
227
228 for (; *pgp; pgp = &(*pgp)->pg_hforw)
229 if (*pgp == pgrp) {
230 *pgp = pgrp->pg_hforw;
231 goto done;
232 }
2e8f8cae 233 panic("pgdelete: can't find pgrp on hash chain");
8fe87cbb
MT
234done:
235 if (--pgrp->pg_session->s_count == 0)
236 FREE(pgrp->pg_session, M_SESSION);
237 FREE(pgrp, M_PGRP);
238}
239
1d348849
MK
240/*
241 * init the process queues
242 */
243pqinit()
244{
245 register struct proc *p;
246
247 /*
248 * most procs are initially on freequeue
249 * nb: we place them there in their "natural" order.
250 */
251
252 freeproc = NULL;
253 for (p = procNPROC; --p > proc; freeproc = p)
254 p->p_nxt = freeproc;
255
256 /*
257 * but proc[0] is special ...
258 */
259
260 allproc = p;
261 p->p_nxt = NULL;
262 p->p_prev = &allproc;
263
264 zombproc = NULL;
265}
8fe87cbb
MT
266
267/* DEBUG */
268pgrpdump()
269{
270 register struct pgrp *pgrp;
271 register struct proc *p;
272 register i;
273
274 for (i=0; i<PIDHSZ; i++) {
275 if (pgrphash[i]) {
276 printf("\tindx %d\n", i);
277 for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
278 printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
279 pgrp, pgrp->pg_id, pgrp->pg_session,
280 pgrp->pg_session->s_count, pgrp->pg_mem);
281 for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
282 printf("\t\tpid %d addr %x pgrp %x\n",
283 p->p_pid, p, p->p_pgrp);
284 }
285 }
286
287 }
288 }
289}