Commit | Line | Data |
---|---|---|
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 | 36 | spgrp(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 | 73 | inferior(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 | |
82 | struct proc * | |
83 | pfind(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 | */ | |
98 | struct pgrp * | |
99 | pgfind(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 | */ | |
113 | pgmv(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 |
176 | done: |
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 | */ | |
202 | pgrm(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 |
214 | done: |
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 | */ | |
223 | pgdelete(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 |
234 | done: |
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 | */ | |
243 | pqinit() | |
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 */ | |
268 | pgrpdump() | |
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 | } |