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.13 (Berkeley) 12/05/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 "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 #include "machine/reg.h" 29 #include "machine/psl.h" 30 31 /* 32 * Is p an inferior of the current process? 33 */ 34 inferior(p) 35 register struct proc *p; 36 { 37 38 for (; p != u.u_procp; p = p->p_pptr) 39 if (p->p_ppid == 0) 40 return (0); 41 return (1); 42 } 43 44 /* 45 * Locate a process by number 46 */ 47 struct proc * 48 pfind(pid) 49 register pid; 50 { 51 register struct proc *p = pidhash[PIDHASH(pid)]; 52 53 for (; p; p = p->p_hash) 54 if (p->p_pid == pid) 55 return (p); 56 return ((struct proc *)0); 57 } 58 59 /* 60 * Locate a process group by number 61 */ 62 struct pgrp * 63 pgfind(pgid) 64 register pid_t pgid; 65 { 66 register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; 67 68 for (; pgrp; pgrp = pgrp->pg_hforw) 69 if (pgrp->pg_id == pgid) 70 return (pgrp); 71 return ((struct pgrp *)0); 72 } 73 74 /* 75 * Move p to a new or existing process group (and session) 76 */ 77 pgmv(p, pgid, mksess) 78 register struct proc *p; 79 pid_t pgid; 80 { 81 register struct pgrp *pgrp = pgfind(pgid); 82 register struct proc **pp; 83 register struct proc *cp; 84 int n; 85 86 #ifdef DIAGNOSTIC 87 if (pgrp && mksess) /* firewalls */ 88 panic("pgmv: setsid into non-empty pgrp"); 89 if (SESS_LEADER(p)) 90 panic("pgmv: session leader attempted setpgrp"); 91 #endif 92 if (pgrp == NULL) { 93 /* 94 * new process group 95 */ 96 #ifdef DIAGNOSTIC 97 if (p->p_pid != pgid) 98 panic("pgmv: new pgrp and pid != pgid"); 99 #endif 100 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 101 M_WAITOK); 102 if (mksess) { 103 register struct session *sess; 104 /* 105 * new session 106 */ 107 MALLOC(sess, struct session *, sizeof(struct session), 108 M_SESSION, M_WAITOK); 109 sess->s_leader = p; 110 sess->s_count = 1; 111 sess->s_ttyvp = NULL; 112 sess->s_ttyp = NULL; 113 p->p_flag &= ~SCTTY; 114 pgrp->pg_session = sess; 115 #ifdef DIAGNOSTIC 116 if (p != u.u_procp) 117 panic("pgmv: mksession and p != u.u_procp"); 118 #endif 119 } else { 120 pgrp->pg_session = p->p_session; 121 pgrp->pg_session->s_count++; 122 } 123 pgrp->pg_id = pgid; 124 pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)]; 125 pgrphash[n] = pgrp; 126 pgrp->pg_jobc = 0; 127 pgrp->pg_mem = NULL; 128 } else if (pgrp == p->p_pgrp) 129 return; 130 131 /* 132 * Adjust eligibility of affected pgrps to participate in job control. 133 * Increment eligibility counts before decrementing, otherwise we 134 * could reach 0 spuriously during the first call. 135 */ 136 fixjobc(p, pgrp, 1); 137 fixjobc(p, p->p_pgrp, 0); 138 139 /* 140 * unlink p from old process group 141 */ 142 for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) 143 if (*pp == p) { 144 *pp = p->p_pgrpnxt; 145 goto done; 146 } 147 panic("pgmv: can't find p on old pgrp"); 148 done: 149 /* 150 * delete old if empty 151 */ 152 if (p->p_pgrp->pg_mem == 0) 153 pgdelete(p->p_pgrp); 154 /* 155 * link into new one 156 */ 157 p->p_pgrp = pgrp; 158 p->p_pgrpnxt = pgrp->pg_mem; 159 pgrp->pg_mem = p; 160 } 161 162 /* 163 * remove process from process group 164 */ 165 pgrm(p) 166 register struct proc *p; 167 { 168 register struct proc **pp = &p->p_pgrp->pg_mem; 169 170 for (; *pp; pp = &(*pp)->p_pgrpnxt) 171 if (*pp == p) { 172 *pp = p->p_pgrpnxt; 173 goto done; 174 } 175 panic("pgrm: can't find p in pgrp"); 176 done: 177 if (!p->p_pgrp->pg_mem) 178 pgdelete(p->p_pgrp); 179 p->p_pgrp = 0; 180 } 181 182 /* 183 * delete a process group 184 */ 185 pgdelete(pgrp) 186 register struct pgrp *pgrp; 187 { 188 register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 189 190 if (pgrp->pg_session->s_ttyp != NULL && 191 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 192 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 193 for (; *pgp; pgp = &(*pgp)->pg_hforw) 194 if (*pgp == pgrp) { 195 *pgp = pgrp->pg_hforw; 196 goto done; 197 } 198 panic("pgdelete: can't find pgrp on hash chain"); 199 done: 200 if (--pgrp->pg_session->s_count == 0) 201 FREE(pgrp->pg_session, M_SESSION); 202 FREE(pgrp, M_PGRP); 203 } 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 /* 272 * init the process queues 273 */ 274 pqinit() 275 { 276 register struct proc *p; 277 278 /* 279 * most procs are initially on freequeue 280 * nb: we place them there in their "natural" order. 281 */ 282 283 freeproc = NULL; 284 for (p = procNPROC; --p > proc; freeproc = p) 285 p->p_nxt = freeproc; 286 287 /* 288 * but proc[0] is special ... 289 */ 290 291 allproc = p; 292 p->p_nxt = NULL; 293 p->p_prev = &allproc; 294 295 zombproc = NULL; 296 } 297 298 #ifdef debug 299 /* DEBUG */ 300 pgrpdump() 301 { 302 register struct pgrp *pgrp; 303 register struct proc *p; 304 register i; 305 306 for (i=0; i<PIDHSZ; i++) { 307 if (pgrphash[i]) { 308 printf("\tindx %d\n", i); 309 for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 310 printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 311 pgrp, pgrp->pg_id, pgrp->pg_session, 312 pgrp->pg_session->s_count, pgrp->pg_mem); 313 for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 314 printf("\t\tpid %d addr %x pgrp %x\n", 315 p->p_pid, p, p->p_pgrp); 316 } 317 } 318 319 } 320 } 321 } 322 #endif /* debug */ 323