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