1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)kern_proc.c 7.12 (Berkeley) 12/01/90 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "map.h" 13 #include "user.h" 14 #include "kernel.h" 15 #include "proc.h" 16 #include "buf.h" 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 "../ufs/quota.h" 24 #include "uio.h" 25 #include "malloc.h" 26 #include "mbuf.h" 27 #include "ioctl.h" 28 #include "tty.h" 29 30 #include "machine/reg.h" 31 #include "machine/pte.h" 32 #include "machine/psl.h" 33 34 /* 35 * Is p an inferior of the current process? 36 */ 37 inferior(p) 38 register struct proc *p; 39 { 40 41 for (; p != u.u_procp; p = p->p_pptr) 42 if (p->p_ppid == 0) 43 return (0); 44 return (1); 45 } 46 47 /* 48 * Locate a process by number 49 */ 50 struct proc * 51 pfind(pid) 52 register pid; 53 { 54 register struct proc *p = pidhash[PIDHASH(pid)]; 55 56 for (; p; p = p->p_hash) 57 if (p->p_pid == pid) 58 return (p); 59 return ((struct proc *)0); 60 } 61 62 /* 63 * Locate a process group by number 64 */ 65 struct pgrp * 66 pgfind(pgid) 67 register pid_t pgid; 68 { 69 register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; 70 71 for (; pgrp; pgrp = pgrp->pg_hforw) 72 if (pgrp->pg_id == pgid) 73 return (pgrp); 74 return ((struct pgrp *)0); 75 } 76 77 /* 78 * Move p to a new or existing process group (and session) 79 */ 80 pgmv(p, pgid, mksess) 81 register struct proc *p; 82 pid_t pgid; 83 { 84 register struct pgrp *pgrp = pgfind(pgid); 85 register struct proc **pp; 86 register struct proc *cp; 87 int n; 88 89 #ifdef DIAGNOSTIC 90 if (pgrp && mksess) /* firewalls */ 91 panic("pgmv: setsid into non-empty pgrp"); 92 if (SESS_LEADER(p)) 93 panic("pgmv: session leader attempted setpgrp"); 94 #endif 95 if (pgrp == NULL) { 96 /* 97 * new process group 98 */ 99 #ifdef DIAGNOSTIC 100 if (p->p_pid != pgid) 101 panic("pgmv: new pgrp and pid != pgid"); 102 #endif 103 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 104 M_WAITOK); 105 if (mksess) { 106 register struct session *sess; 107 /* 108 * new session 109 */ 110 MALLOC(sess, struct session *, sizeof(struct session), 111 M_SESSION, M_WAITOK); 112 sess->s_leader = p; 113 sess->s_count = 1; 114 sess->s_ttyvp = NULL; 115 sess->s_ttyp = NULL; 116 p->p_flag &= ~SCTTY; 117 pgrp->pg_session = sess; 118 #ifdef DIAGNOSTIC 119 if (p != u.u_procp) 120 panic("pgmv: mksession and p != u.u_procp"); 121 #endif 122 } else { 123 pgrp->pg_session = p->p_session; 124 pgrp->pg_session->s_count++; 125 } 126 pgrp->pg_id = pgid; 127 pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)]; 128 pgrphash[n] = pgrp; 129 pgrp->pg_jobc = 0; 130 pgrp->pg_mem = NULL; 131 } else if (pgrp == p->p_pgrp) 132 return; 133 134 /* 135 * Adjust eligibility of affected pgrps to participate in job control. 136 * Increment eligibility counts before decrementing, otherwise we 137 * could reach 0 spuriously during the first call. 138 */ 139 fixjobc(p, pgrp, 1); 140 fixjobc(p, p->p_pgrp, 0); 141 142 /* 143 * unlink p from old process group 144 */ 145 for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) 146 if (*pp == p) { 147 *pp = p->p_pgrpnxt; 148 goto done; 149 } 150 panic("pgmv: can't find p on old pgrp"); 151 done: 152 /* 153 * delete old if empty 154 */ 155 if (p->p_pgrp->pg_mem == 0) 156 pgdelete(p->p_pgrp); 157 /* 158 * link into new one 159 */ 160 p->p_pgrp = pgrp; 161 p->p_pgrpnxt = pgrp->pg_mem; 162 pgrp->pg_mem = p; 163 } 164 165 /* 166 * remove process from process group 167 */ 168 pgrm(p) 169 register struct proc *p; 170 { 171 register struct proc **pp = &p->p_pgrp->pg_mem; 172 173 for (; *pp; pp = &(*pp)->p_pgrpnxt) 174 if (*pp == p) { 175 *pp = p->p_pgrpnxt; 176 goto done; 177 } 178 panic("pgrm: can't find p in pgrp"); 179 done: 180 if (!p->p_pgrp->pg_mem) 181 pgdelete(p->p_pgrp); 182 p->p_pgrp = 0; 183 } 184 185 /* 186 * delete a process group 187 */ 188 pgdelete(pgrp) 189 register struct pgrp *pgrp; 190 { 191 register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 192 193 if (pgrp->pg_session->s_ttyp != NULL && 194 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 195 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 196 for (; *pgp; pgp = &(*pgp)->pg_hforw) 197 if (*pgp == pgrp) { 198 *pgp = pgrp->pg_hforw; 199 goto done; 200 } 201 panic("pgdelete: can't find pgrp on hash chain"); 202 done: 203 if (--pgrp->pg_session->s_count == 0) 204 FREE(pgrp->pg_session, M_SESSION); 205 FREE(pgrp, M_PGRP); 206 } 207 208 /* 209 * Adjust pgrp jobc counters when specified process changes process group. 210 * We count the number of processes in each process group that "qualify" 211 * the group for terminal job control (those with a parent in a different 212 * process group of the same session). If that count reaches zero, the 213 * process group becomes orphaned. Check both the specified process' 214 * process group and that of its children. 215 * entering == 0 => p is leaving specified group. 216 * entering == 1 => p is entering specified group. 217 */ 218 fixjobc(p, pgrp, entering) 219 register struct proc *p; 220 register struct pgrp *pgrp; 221 int entering; 222 { 223 register struct pgrp *hispgrp; 224 register struct session *mysession = pgrp->pg_session; 225 226 /* 227 * Check p's parent to see whether p qualifies its own process 228 * group; if so, adjust count for p's process group. 229 */ 230 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 231 hispgrp->pg_session == mysession) 232 if (entering) 233 pgrp->pg_jobc++; 234 else if (--pgrp->pg_jobc == 0) 235 orphanpg(pgrp); 236 237 /* 238 * Check this process' children to see whether they qualify 239 * their process groups; if so, adjust counts for children's 240 * process groups. 241 */ 242 for (p = p->p_cptr; p; p = p->p_osptr) 243 if ((hispgrp = p->p_pgrp) != pgrp && 244 hispgrp->pg_session == mysession && 245 p->p_stat != SZOMB) 246 if (entering) 247 hispgrp->pg_jobc++; 248 else if (--hispgrp->pg_jobc == 0) 249 orphanpg(hispgrp); 250 } 251 252 /* 253 * A process group has become orphaned; 254 * if there are any stopped processes in the group, 255 * hang-up all process in that group. 256 */ 257 static 258 orphanpg(pg) 259 struct pgrp *pg; 260 { 261 register struct proc *p; 262 263 for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { 264 if (p->p_stat == SSTOP) { 265 for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { 266 psignal(p, SIGHUP); 267 psignal(p, SIGCONT); 268 } 269 return; 270 } 271 } 272 } 273 274 /* 275 * init the process queues 276 */ 277 pqinit() 278 { 279 register struct proc *p; 280 281 /* 282 * most procs are initially on freequeue 283 * nb: we place them there in their "natural" order. 284 */ 285 286 freeproc = NULL; 287 for (p = procNPROC; --p > proc; freeproc = p) 288 p->p_nxt = freeproc; 289 290 /* 291 * but proc[0] is special ... 292 */ 293 294 allproc = p; 295 p->p_nxt = NULL; 296 p->p_prev = &allproc; 297 298 zombproc = NULL; 299 } 300 301 #ifdef debug 302 /* DEBUG */ 303 pgrpdump() 304 { 305 register struct pgrp *pgrp; 306 register struct proc *p; 307 register i; 308 309 for (i=0; i<PIDHSZ; i++) { 310 if (pgrphash[i]) { 311 printf("\tindx %d\n", i); 312 for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 313 printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 314 pgrp, pgrp->pg_id, pgrp->pg_session, 315 pgrp->pg_session->s_count, pgrp->pg_mem); 316 for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 317 printf("\t\tpid %d addr %x pgrp %x\n", 318 p->p_pid, p, p->p_pgrp); 319 } 320 } 321 322 } 323 } 324 } 325 #endif /* debug */ 326