p_devtmp => p_dupfd; eliminate u.u_error from RETURN macro
[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 *
b3ce9b0f 17 * @(#)kern_proc.c 7.9 (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"
5b6ff773 37#include "ioctl.h"
8fe87cbb 38#include "tty.h"
a1bce776 39
d301d150
KM
40#include "machine/reg.h"
41#include "machine/pte.h"
42#include "machine/psl.h"
43
bdf8c113 44/*
f6ab5a0c 45 * Clear any pending stops for top and all descendents.
bdf8c113 46 */
f6ab5a0c 47spgrp(top)
bdf8c113 48 struct proc *top;
4147b3f6 49{
bdf8c113 50 register struct proc *p;
4147b3f6
BJ
51 int f = 0;
52
bdf8c113
MK
53 p = top;
54 for (;;) {
f6ab5a0c 55 p->p_sig &=
bdf8c113 56 ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU));
4147b3f6
BJ
57 f++;
58 /*
bdf8c113
MK
59 * If this process has children, descend to them next,
60 * otherwise do any siblings, and if done with this level,
61 * follow back up the tree (but not past top).
4147b3f6 62 */
bdf8c113
MK
63 if (p->p_cptr)
64 p = p->p_cptr;
65 else if (p == top)
66 return (f);
67 else if (p->p_osptr)
68 p = p->p_osptr;
69 else for (;;) {
70 p = p->p_pptr;
71 if (p == top)
72 return (f);
bdf8c113
MK
73 if (p->p_osptr) {
74 p = p->p_osptr;
75 break;
76 }
77 }
4147b3f6 78 }
4147b3f6
BJ
79}
80
29dd101b 81/*
4147b3f6 82 * Is p an inferior of the current process?
29dd101b 83 */
4147b3f6 84inferior(p)
a2a2a0d6 85 register struct proc *p;
29dd101b 86{
4147b3f6
BJ
87 for (; p != u.u_procp; p = p->p_pptr)
88 if (p->p_ppid == 0)
89 return (0);
90 return (1);
29dd101b 91}
a2a2a0d6 92
b3ce9b0f
MK
93/*
94 * Locate a process by number
95 */
a2a2a0d6
BJ
96struct proc *
97pfind(pid)
8fe87cbb 98 register pid;
a2a2a0d6 99{
b3ce9b0f 100 register struct proc *p = pidhash[PIDHASH(pid)];
a2a2a0d6 101
b3ce9b0f 102 for (; p; p = p->p_hash)
a2a2a0d6
BJ
103 if (p->p_pid == pid)
104 return (p);
105 return ((struct proc *)0);
106}
1d348849 107
8fe87cbb
MT
108/*
109 * Locate a process group by number
110 */
111struct pgrp *
112pgfind(pgid)
113 register pid_t pgid;
114{
115 register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
116
117 for (; pgrp; pgrp = pgrp->pg_hforw)
118 if (pgrp->pg_id == pgid)
b3ce9b0f 119 return (pgrp);
8fe87cbb
MT
120 return ((struct pgrp *)0);
121}
122
123/*
124 * Move p to a new or existing process group (and session)
125 */
126pgmv(p, pgid, mksess)
127 register struct proc *p;
128 pid_t pgid;
129{
130 register struct pgrp *pgrp = pgfind(pgid);
131 register struct proc **pp = &p->p_pgrp->pg_mem;
132 register struct proc *cp;
2e8f8cae 133 struct pgrp *opgrp;
8fe87cbb
MT
134 register n;
135
944e89dc 136#ifdef DIAGNOSTIC
8fe87cbb 137 if (pgrp && mksess) /* firewalls */
2e8f8cae 138 panic("pgmv: setsid into non-empty pgrp");
8fe87cbb 139 if (SESS_LEADER(p))
2e8f8cae 140 panic("pgmv: session leader attempted setpgrp");
944e89dc 141#endif
2e8f8cae 142 if (pgrp == NULL) {
8fe87cbb
MT
143 /*
144 * new process group
145 */
944e89dc 146#ifdef DIAGNOSTIC
8fe87cbb 147 if (p->p_pid != pgid)
2e8f8cae 148 panic("pgmv: new pgrp and pid != pgid");
944e89dc 149#endif
8fe87cbb
MT
150 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
151 M_WAITOK);
152 if (mksess) {
153 register struct session *sess;
154 /*
155 * new session
156 */
157 MALLOC(sess, struct session *, sizeof(struct session),
158 M_SESSION, M_WAITOK);
159 sess->s_leader = p;
160 sess->s_count = 1;
944e89dc
MT
161 sess->s_ttyvp = NULL;
162 sess->s_ttyp = NULL;
163 p->p_flag &= ~SCTTY;
8fe87cbb 164 pgrp->pg_session = sess;
944e89dc 165#ifdef DIAGNOSTIC
8fe87cbb
MT
166 if (p != u.u_procp)
167 panic("pgmv: mksession and p != u.u_procp");
944e89dc 168#endif
8fe87cbb
MT
169 } else {
170 pgrp->pg_session = p->p_session;
171 pgrp->pg_session->s_count++;
172 }
173 pgrp->pg_id = pgid;
174 pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)];
175 pgrphash[n] = pgrp;
176 pgrp->pg_jobc = 0;
944e89dc 177 pgrp->pg_mem = NULL;
8fe87cbb
MT
178 }
179 /*
180 * adjust eligibility of affected pgrps to participate in job control
181 */
182 if (PGRP_JOBC(p))
183 p->p_pgrp->pg_jobc--;
184 for (cp = p->p_cptr; cp; cp = cp->p_osptr)
185 if (PGRP_JOBC(cp))
186 cp->p_pgrp->pg_jobc--;
187 /*
188 * unlink p from old process group
189 */
190 for (; *pp; pp = &(*pp)->p_pgrpnxt)
191 if (*pp == p) {
192 *pp = p->p_pgrpnxt;
193 goto done;
194 }
2e8f8cae 195 panic("pgmv: can't find p on old pgrp");
8fe87cbb
MT
196done:
197 /*
198 * link into new one
199 */
200 p->p_pgrpnxt = pgrp->pg_mem;
201 pgrp->pg_mem = p;
2e8f8cae 202 opgrp = p->p_pgrp;
8fe87cbb
MT
203 p->p_pgrp = pgrp;
204 /*
205 * adjust eligibility of affected pgrps to participate in job control
206 */
207 if (PGRP_JOBC(p))
208 p->p_pgrp->pg_jobc++;
209 for (cp = p->p_cptr; cp; cp = cp->p_osptr)
210 if (PGRP_JOBC(cp))
211 cp->p_pgrp->pg_jobc++;
212 /*
213 * old pgrp empty?
214 */
2e8f8cae
MT
215 if (!opgrp->pg_mem)
216 pgdelete(opgrp);
8fe87cbb
MT
217}
218
219/*
220 * remove process from process group
221 */
222pgrm(p)
223 register struct proc *p;
224{
225 register struct proc **pp = &p->p_pgrp->pg_mem;
8fe87cbb
MT
226
227 for (; *pp; pp = &(*pp)->p_pgrpnxt)
228 if (*pp == p) {
229 *pp = p->p_pgrpnxt;
230 goto done;
231 }
2e8f8cae 232 panic("pgrm: can't find p in pgrp");
8fe87cbb
MT
233done:
234 if (!p->p_pgrp->pg_mem)
235 pgdelete(p->p_pgrp);
236 p->p_pgrp = 0;
237}
238
239/*
240 * delete a process group
241 */
242pgdelete(pgrp)
243 register struct pgrp *pgrp;
244{
245 register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
246
944e89dc
MT
247 if (pgrp->pg_session->s_ttyp != NULL &&
248 pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
249 pgrp->pg_session->s_ttyp->t_pgrp = NULL;
8fe87cbb
MT
250 for (; *pgp; pgp = &(*pgp)->pg_hforw)
251 if (*pgp == pgrp) {
252 *pgp = pgrp->pg_hforw;
253 goto done;
254 }
2e8f8cae 255 panic("pgdelete: can't find pgrp on hash chain");
8fe87cbb
MT
256done:
257 if (--pgrp->pg_session->s_count == 0)
258 FREE(pgrp->pg_session, M_SESSION);
259 FREE(pgrp, M_PGRP);
260}
261
1d348849
MK
262/*
263 * init the process queues
264 */
265pqinit()
266{
267 register struct proc *p;
268
269 /*
270 * most procs are initially on freequeue
271 * nb: we place them there in their "natural" order.
272 */
273
274 freeproc = NULL;
275 for (p = procNPROC; --p > proc; freeproc = p)
276 p->p_nxt = freeproc;
277
278 /*
279 * but proc[0] is special ...
280 */
281
282 allproc = p;
283 p->p_nxt = NULL;
284 p->p_prev = &allproc;
285
286 zombproc = NULL;
287}
8fe87cbb 288
c4ec2128 289#ifdef debug
8fe87cbb
MT
290/* DEBUG */
291pgrpdump()
292{
293 register struct pgrp *pgrp;
294 register struct proc *p;
295 register i;
296
297 for (i=0; i<PIDHSZ; i++) {
298 if (pgrphash[i]) {
299 printf("\tindx %d\n", i);
300 for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
301 printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
302 pgrp, pgrp->pg_id, pgrp->pg_session,
303 pgrp->pg_session->s_count, pgrp->pg_mem);
304 for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
305 printf("\t\tpid %d addr %x pgrp %x\n",
306 p->p_pid, p, p->p_pgrp);
307 }
308 }
309
310 }
311 }
312}
c4ec2128 313#endif /* debug */