1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 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) 05/09/89 18 */ 19 20 #include "param.h" 21 #include "systm.h" 22 #include "map.h" 23 #include "user.h" 24 #include "kernel.h" 25 #include "proc.h" 26 #include "buf.h" 27 #include "seg.h" 28 #include "acct.h" 29 #include "wait.h" 30 #include "vm.h" 31 #include "text.h" 32 #include "file.h" 33 #include "../ufs/quota.h" 34 #include "uio.h" 35 #include "malloc.h" 36 #include "mbuf.h" 37 #include "tty.h" 38 39 #include "machine/reg.h" 40 #include "machine/pte.h" 41 #include "machine/psl.h" 42 43 /* 44 * Clear any pending stops for top and all descendents. 45 */ 46 spgrp(top) 47 struct proc *top; 48 { 49 register struct proc *p; 50 int f = 0; 51 52 p = top; 53 for (;;) { 54 p->p_sig &= 55 ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU)); 56 f++; 57 /* 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). 61 */ 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); 72 if (p->p_osptr) { 73 p = p->p_osptr; 74 break; 75 } 76 } 77 } 78 } 79 80 /* 81 * Is p an inferior of the current process? 82 */ 83 inferior(p) 84 register struct proc *p; 85 { 86 for (; p != u.u_procp; p = p->p_pptr) 87 if (p->p_ppid == 0) 88 return (0); 89 return (1); 90 } 91 92 struct proc * 93 pfind(pid) 94 register pid; 95 { 96 register struct proc *p; 97 98 for (p = &proc[pidhash[PIDHASH(pid)]] ; 99 p != &proc[0]; p = &proc[p->p_idhash]) 100 if (p->p_pid == pid) 101 return (p); 102 return ((struct proc *)0); 103 } 104 105 /* 106 * Locate a process group by number 107 */ 108 struct pgrp * 109 pgfind(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 */ 123 pgmv(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; 130 struct pgrp *opgrp; 131 register n; 132 133 if (pgrp && mksess) /* firewalls */ 134 panic("pgmv: setsid into non-empty pgrp"); 135 if (SESS_LEADER(p)) 136 panic("pgmv: session leader attempted setpgrp"); 137 if (pgrp == NULL) { 138 /* 139 * new process group 140 */ 141 if (p->p_pid != pgid) 142 panic("pgmv: new pgrp and pid != pgid"); 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"); 157 u.u_ttyp = NULL; 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 } 185 panic("pgmv: can't find p on old pgrp"); 186 done: 187 /* 188 * link into new one 189 */ 190 p->p_pgrpnxt = pgrp->pg_mem; 191 pgrp->pg_mem = p; 192 opgrp = p->p_pgrp; 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 */ 205 if (!opgrp->pg_mem) 206 pgdelete(opgrp); 207 } 208 209 /* 210 * remove process from process group 211 */ 212 pgrm(p) 213 register struct proc *p; 214 { 215 register struct proc **pp = &p->p_pgrp->pg_mem; 216 217 for (; *pp; pp = &(*pp)->p_pgrpnxt) 218 if (*pp == p) { 219 *pp = p->p_pgrpnxt; 220 goto done; 221 } 222 panic("pgrm: can't find p in pgrp"); 223 done: 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 */ 232 pgdelete(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 } 242 panic("pgdelete: can't find pgrp on hash chain"); 243 done: 244 if (--pgrp->pg_session->s_count == 0) 245 FREE(pgrp->pg_session, M_SESSION); 246 FREE(pgrp, M_PGRP); 247 } 248 249 /* 250 * init the process queues 251 */ 252 pqinit() 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 } 275 276 #ifdef debug 277 /* DEBUG */ 278 pgrpdump() 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 } 300 #endif /* debug */ 301