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