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.9 (Berkeley) 04/03/90 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 "ioctl.h" 38 #include "tty.h" 39 40 #include "machine/reg.h" 41 #include "machine/pte.h" 42 #include "machine/psl.h" 43 44 /* 45 * Clear any pending stops for top and all descendents. 46 */ 47 spgrp(top) 48 struct proc *top; 49 { 50 register struct proc *p; 51 int f = 0; 52 53 p = top; 54 for (;;) { 55 p->p_sig &= 56 ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU)); 57 f++; 58 /* 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). 62 */ 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); 73 if (p->p_osptr) { 74 p = p->p_osptr; 75 break; 76 } 77 } 78 } 79 } 80 81 /* 82 * Is p an inferior of the current process? 83 */ 84 inferior(p) 85 register struct proc *p; 86 { 87 for (; p != u.u_procp; p = p->p_pptr) 88 if (p->p_ppid == 0) 89 return (0); 90 return (1); 91 } 92 93 /* 94 * Locate a process by number 95 */ 96 struct proc * 97 pfind(pid) 98 register pid; 99 { 100 register struct proc *p = pidhash[PIDHASH(pid)]; 101 102 for (; p; p = p->p_hash) 103 if (p->p_pid == pid) 104 return (p); 105 return ((struct proc *)0); 106 } 107 108 /* 109 * Locate a process group by number 110 */ 111 struct pgrp * 112 pgfind(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) 119 return (pgrp); 120 return ((struct pgrp *)0); 121 } 122 123 /* 124 * Move p to a new or existing process group (and session) 125 */ 126 pgmv(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; 133 struct pgrp *opgrp; 134 register n; 135 136 #ifdef DIAGNOSTIC 137 if (pgrp && mksess) /* firewalls */ 138 panic("pgmv: setsid into non-empty pgrp"); 139 if (SESS_LEADER(p)) 140 panic("pgmv: session leader attempted setpgrp"); 141 #endif 142 if (pgrp == NULL) { 143 /* 144 * new process group 145 */ 146 #ifdef DIAGNOSTIC 147 if (p->p_pid != pgid) 148 panic("pgmv: new pgrp and pid != pgid"); 149 #endif 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; 161 sess->s_ttyvp = NULL; 162 sess->s_ttyp = NULL; 163 p->p_flag &= ~SCTTY; 164 pgrp->pg_session = sess; 165 #ifdef DIAGNOSTIC 166 if (p != u.u_procp) 167 panic("pgmv: mksession and p != u.u_procp"); 168 #endif 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; 177 pgrp->pg_mem = NULL; 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 } 195 panic("pgmv: can't find p on old pgrp"); 196 done: 197 /* 198 * link into new one 199 */ 200 p->p_pgrpnxt = pgrp->pg_mem; 201 pgrp->pg_mem = p; 202 opgrp = p->p_pgrp; 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 */ 215 if (!opgrp->pg_mem) 216 pgdelete(opgrp); 217 } 218 219 /* 220 * remove process from process group 221 */ 222 pgrm(p) 223 register struct proc *p; 224 { 225 register struct proc **pp = &p->p_pgrp->pg_mem; 226 227 for (; *pp; pp = &(*pp)->p_pgrpnxt) 228 if (*pp == p) { 229 *pp = p->p_pgrpnxt; 230 goto done; 231 } 232 panic("pgrm: can't find p in pgrp"); 233 done: 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 */ 242 pgdelete(pgrp) 243 register struct pgrp *pgrp; 244 { 245 register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 246 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; 250 for (; *pgp; pgp = &(*pgp)->pg_hforw) 251 if (*pgp == pgrp) { 252 *pgp = pgrp->pg_hforw; 253 goto done; 254 } 255 panic("pgdelete: can't find pgrp on hash chain"); 256 done: 257 if (--pgrp->pg_session->s_count == 0) 258 FREE(pgrp->pg_session, M_SESSION); 259 FREE(pgrp, M_PGRP); 260 } 261 262 /* 263 * init the process queues 264 */ 265 pqinit() 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 } 288 289 #ifdef debug 290 /* DEBUG */ 291 pgrpdump() 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 } 313 #endif /* debug */ 314