1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)kern_proc.c 8.3 (Berkeley) 09/23/93 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 * Structure associated with user cacheing. 28 */ 29 struct uidinfo { 30 struct uidinfo *ui_next; 31 struct uidinfo **ui_prev; 32 uid_t ui_uid; 33 long ui_proccnt; 34 } **uihashtbl; 35 u_long uihash; /* size of hash table - 1 */ 36 #define UIHASH(uid) ((uid) & uihash) 37 38 /* 39 * Allocate a hash table. 40 */ 41 usrinfoinit() 42 { 43 44 uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash); 45 } 46 47 /* 48 * Change the count associated with number of processes 49 * a given user is using. 50 */ 51 int 52 chgproccnt(uid, diff) 53 uid_t uid; 54 int diff; 55 { 56 register struct uidinfo **uipp, *uip, *uiq; 57 58 uipp = &uihashtbl[UIHASH(uid)]; 59 for (uip = *uipp; uip; uip = uip->ui_next) 60 if (uip->ui_uid == uid) 61 break; 62 if (uip) { 63 uip->ui_proccnt += diff; 64 if (uip->ui_proccnt > 0) 65 return (uip->ui_proccnt); 66 if (uip->ui_proccnt < 0) 67 panic("chgproccnt: procs < 0"); 68 if (uiq = uip->ui_next) 69 uiq->ui_prev = uip->ui_prev; 70 *uip->ui_prev = uiq; 71 FREE(uip, M_PROC); 72 return (0); 73 } 74 if (diff <= 0) { 75 if (diff == 0) 76 return(0); 77 panic("chgproccnt: lost user"); 78 } 79 MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK); 80 if (uiq = *uipp) 81 uiq->ui_prev = &uip->ui_next; 82 uip->ui_next = uiq; 83 uip->ui_prev = uipp; 84 *uipp = uip; 85 uip->ui_uid = uid; 86 uip->ui_proccnt = diff; 87 return (diff); 88 } 89 90 /* 91 * Is p an inferior of the current process? 92 */ 93 inferior(p) 94 register struct proc *p; 95 { 96 97 for (; p != curproc; p = p->p_pptr) 98 if (p->p_pid == 0) 99 return (0); 100 return (1); 101 } 102 103 /* 104 * Locate a process by number 105 */ 106 struct proc * 107 pfind(pid) 108 register pid_t pid; 109 { 110 register struct proc *p; 111 112 for (p = pidhash[PIDHASH(pid)]; p != NULL; p = p->p_hash) 113 if (p->p_pid == pid) 114 return (p); 115 return (NULL); 116 } 117 118 /* 119 * Locate a process group by number 120 */ 121 struct pgrp * 122 pgfind(pgid) 123 register pid_t pgid; 124 { 125 register struct pgrp *pgrp; 126 127 for (pgrp = pgrphash[PIDHASH(pgid)]; 128 pgrp != NULL; pgrp = pgrp->pg_hforw) 129 if (pgrp->pg_id == pgid) 130 return (pgrp); 131 return (NULL); 132 } 133 134 /* 135 * Move p to a new or existing process group (and session) 136 */ 137 enterpgrp(p, pgid, mksess) 138 register struct proc *p; 139 pid_t pgid; 140 int mksess; 141 { 142 register struct pgrp *pgrp = pgfind(pgid); 143 register struct proc **pp; 144 register struct proc *cp; 145 int n; 146 147 #ifdef DIAGNOSTIC 148 if (pgrp != NULL && mksess) /* firewalls */ 149 panic("enterpgrp: setsid into non-empty pgrp"); 150 if (SESS_LEADER(p)) 151 panic("enterpgrp: session leader attempted setpgrp"); 152 #endif 153 if (pgrp == NULL) { 154 pid_t savepid = p->p_pid; 155 struct proc *np; 156 /* 157 * new process group 158 */ 159 #ifdef DIAGNOSTIC 160 if (p->p_pid != pgid) 161 panic("enterpgrp: new pgrp and pid != pgid"); 162 #endif 163 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, 164 M_WAITOK); 165 if ((np = pfind(savepid)) == NULL || np != p) 166 return (ESRCH); 167 if (mksess) { 168 register struct session *sess; 169 170 /* 171 * new session 172 */ 173 MALLOC(sess, struct session *, sizeof(struct session), 174 M_SESSION, M_WAITOK); 175 sess->s_leader = p; 176 sess->s_count = 1; 177 sess->s_ttyvp = NULL; 178 sess->s_ttyp = NULL; 179 bcopy(p->p_session->s_login, sess->s_login, 180 sizeof(sess->s_login)); 181 p->p_flag &= ~P_CONTROLT; 182 pgrp->pg_session = sess; 183 #ifdef DIAGNOSTIC 184 if (p != curproc) 185 panic("enterpgrp: mksession and p != curproc"); 186 #endif 187 } else { 188 pgrp->pg_session = p->p_session; 189 pgrp->pg_session->s_count++; 190 } 191 pgrp->pg_id = pgid; 192 pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)]; 193 pgrphash[n] = pgrp; 194 pgrp->pg_jobc = 0; 195 pgrp->pg_mem = NULL; 196 } else if (pgrp == p->p_pgrp) 197 return (0); 198 199 /* 200 * Adjust eligibility of affected pgrps to participate in job control. 201 * Increment eligibility counts before decrementing, otherwise we 202 * could reach 0 spuriously during the first call. 203 */ 204 fixjobc(p, pgrp, 1); 205 fixjobc(p, p->p_pgrp, 0); 206 207 /* 208 * unlink p from old process group 209 */ 210 for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) { 211 if (*pp == p) { 212 *pp = p->p_pgrpnxt; 213 break; 214 } 215 } 216 #ifdef DIAGNOSTIC 217 if (pp == NULL) 218 panic("enterpgrp: can't find p on old pgrp"); 219 #endif 220 /* 221 * delete old if empty 222 */ 223 if (p->p_pgrp->pg_mem == 0) 224 pgdelete(p->p_pgrp); 225 /* 226 * link into new one 227 */ 228 p->p_pgrp = pgrp; 229 p->p_pgrpnxt = pgrp->pg_mem; 230 pgrp->pg_mem = p; 231 return (0); 232 } 233 234 /* 235 * remove process from process group 236 */ 237 leavepgrp(p) 238 register struct proc *p; 239 { 240 register struct proc **pp = &p->p_pgrp->pg_mem; 241 242 for (; *pp; pp = &(*pp)->p_pgrpnxt) { 243 if (*pp == p) { 244 *pp = p->p_pgrpnxt; 245 break; 246 } 247 } 248 #ifdef DIAGNOSTIC 249 if (pp == NULL) 250 panic("leavepgrp: can't find p in pgrp"); 251 #endif 252 if (!p->p_pgrp->pg_mem) 253 pgdelete(p->p_pgrp); 254 p->p_pgrp = 0; 255 return (0); 256 } 257 258 /* 259 * delete a process group 260 */ 261 pgdelete(pgrp) 262 register struct pgrp *pgrp; 263 { 264 register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; 265 266 if (pgrp->pg_session->s_ttyp != NULL && 267 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 268 pgrp->pg_session->s_ttyp->t_pgrp = NULL; 269 for (; *pgp; pgp = &(*pgp)->pg_hforw) { 270 if (*pgp == pgrp) { 271 *pgp = pgrp->pg_hforw; 272 break; 273 } 274 } 275 #ifdef DIAGNOSTIC 276 if (pgp == NULL) 277 panic("pgdelete: can't find pgrp on hash chain"); 278 #endif 279 if (--pgrp->pg_session->s_count == 0) 280 FREE(pgrp->pg_session, M_SESSION); 281 FREE(pgrp, M_PGRP); 282 } 283 284 static void orphanpg(); 285 286 /* 287 * Adjust pgrp jobc counters when specified process changes process group. 288 * We count the number of processes in each process group that "qualify" 289 * the group for terminal job control (those with a parent in a different 290 * process group of the same session). If that count reaches zero, the 291 * process group becomes orphaned. Check both the specified process' 292 * process group and that of its children. 293 * entering == 0 => p is leaving specified group. 294 * entering == 1 => p is entering specified group. 295 */ 296 fixjobc(p, pgrp, entering) 297 register struct proc *p; 298 register struct pgrp *pgrp; 299 int entering; 300 { 301 register struct pgrp *hispgrp; 302 register struct session *mysession = pgrp->pg_session; 303 304 /* 305 * Check p's parent to see whether p qualifies its own process 306 * group; if so, adjust count for p's process group. 307 */ 308 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && 309 hispgrp->pg_session == mysession) 310 if (entering) 311 pgrp->pg_jobc++; 312 else if (--pgrp->pg_jobc == 0) 313 orphanpg(pgrp); 314 315 /* 316 * Check this process' children to see whether they qualify 317 * their process groups; if so, adjust counts for children's 318 * process groups. 319 */ 320 for (p = p->p_cptr; p; p = p->p_osptr) 321 if ((hispgrp = p->p_pgrp) != pgrp && 322 hispgrp->pg_session == mysession && 323 p->p_stat != SZOMB) 324 if (entering) 325 hispgrp->pg_jobc++; 326 else if (--hispgrp->pg_jobc == 0) 327 orphanpg(hispgrp); 328 } 329 330 /* 331 * A process group has become orphaned; 332 * if there are any stopped processes in the group, 333 * hang-up all process in that group. 334 */ 335 static void 336 orphanpg(pg) 337 struct pgrp *pg; 338 { 339 register struct proc *p; 340 341 for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { 342 if (p->p_stat == SSTOP) { 343 for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { 344 psignal(p, SIGHUP); 345 psignal(p, SIGCONT); 346 } 347 return; 348 } 349 } 350 } 351 352 #ifdef debug 353 /* DEBUG */ 354 pgrpdump() 355 { 356 register struct pgrp *pgrp; 357 register struct proc *p; 358 register i; 359 360 for (i=0; i<PIDHSZ; i++) { 361 if (pgrphash[i]) { 362 printf("\tindx %d\n", i); 363 for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 364 printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 365 pgrp, pgrp->pg_id, pgrp->pg_session, 366 pgrp->pg_session->s_count, pgrp->pg_mem); 367 for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 368 printf("\t\tpid %d addr %x pgrp %x\n", 369 p->p_pid, p, p->p_pgrp); 370 } 371 } 372 373 } 374 } 375 } 376 #endif /* debug */ 377