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