|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms, with or without ! 6: * modification, are permitted provided that the following conditions ! 7: * are met: ! 8: * 1. Redistributions of source code must retain the above copyright ! 9: * notice, this list of conditions and the following disclaimer. ! 10: * 2. Redistributions in binary form must reproduce the above copyright ! 11: * notice, this list of conditions and the following disclaimer in the ! 12: * documentation and/or other materials provided with the distribution. ! 13: * 3. All advertising materials mentioning features or use of this software ! 14: * must display the following acknowledgement: ! 15: * This product includes software developed by the University of ! 16: * California, Berkeley and its contributors. ! 17: * 4. Neither the name of the University nor the names of its contributors ! 18: * may be used to endorse or promote products derived from this software ! 19: * without specific prior written permission. ! 20: * ! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 31: * SUCH DAMAGE. ! 32: * ! 33: * @(#)kern_proc.c 7.16 (Berkeley) 6/28/91 ! 34: */ ! 35: ! 36: #include "param.h" ! 37: #include "systm.h" ! 38: #include "map.h" ! 39: #include "kernel.h" ! 40: #include "proc.h" ! 41: #include "buf.h" ! 42: #include "seg.h" ! 43: #include "acct.h" ! 44: #include "wait.h" ! 45: #include "file.h" ! 46: #include "../ufs/quota.h" ! 47: #include "uio.h" ! 48: #include "malloc.h" ! 49: #include "mbuf.h" ! 50: #include "ioctl.h" ! 51: #include "tty.h" ! 52: ! 53: /* ! 54: * Is p an inferior of the current process? ! 55: */ ! 56: inferior(p) ! 57: register struct proc *p; ! 58: { ! 59: ! 60: for (; p != curproc; p = p->p_pptr) ! 61: if (p->p_pid == 0) ! 62: return (0); ! 63: return (1); ! 64: } ! 65: ! 66: /* ! 67: * Locate a process by number ! 68: */ ! 69: struct proc * ! 70: pfind(pid) ! 71: register pid; ! 72: { ! 73: register struct proc *p = pidhash[PIDHASH(pid)]; ! 74: ! 75: for (; p; p = p->p_hash) ! 76: if (p->p_pid == pid) ! 77: return (p); ! 78: return ((struct proc *)0); ! 79: } ! 80: ! 81: /* ! 82: * Locate a process group by number ! 83: */ ! 84: struct pgrp * ! 85: pgfind(pgid) ! 86: register pid_t pgid; ! 87: { ! 88: register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)]; ! 89: ! 90: for (; pgrp; pgrp = pgrp->pg_hforw) ! 91: if (pgrp->pg_id == pgid) ! 92: return (pgrp); ! 93: return ((struct pgrp *)0); ! 94: } ! 95: ! 96: /* ! 97: * Move p to a new or existing process group (and session) ! 98: */ ! 99: enterpgrp(p, pgid, mksess) ! 100: register struct proc *p; ! 101: pid_t pgid; ! 102: { ! 103: register struct pgrp *pgrp = pgfind(pgid); ! 104: register struct proc **pp; ! 105: register struct proc *cp; ! 106: int n; ! 107: ! 108: #ifdef DIAGNOSTIC ! 109: if (pgrp && mksess) /* firewalls */ ! 110: panic("enterpgrp: setsid into non-empty pgrp"); ! 111: if (SESS_LEADER(p)) ! 112: panic("enterpgrp: session leader attempted setpgrp"); ! 113: #endif ! 114: if (pgrp == NULL) { ! 115: /* ! 116: * new process group ! 117: */ ! 118: #ifdef DIAGNOSTIC ! 119: if (p->p_pid != pgid) ! 120: panic("enterpgrp: new pgrp and pid != pgid"); ! 121: #endif ! 122: MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, ! 123: M_WAITOK); ! 124: if (mksess) { ! 125: register struct session *sess; ! 126: ! 127: /* ! 128: * new session ! 129: */ ! 130: MALLOC(sess, struct session *, sizeof(struct session), ! 131: M_SESSION, M_WAITOK); ! 132: sess->s_leader = p; ! 133: sess->s_count = 1; ! 134: sess->s_ttyvp = NULL; ! 135: sess->s_ttyp = NULL; ! 136: bcopy(p->p_session->s_login, sess->s_login, ! 137: sizeof(sess->s_login)); ! 138: p->p_flag &= ~SCTTY; ! 139: pgrp->pg_session = sess; ! 140: #ifdef DIAGNOSTIC ! 141: if (p != curproc) ! 142: panic("enterpgrp: mksession and p != curproc"); ! 143: #endif ! 144: } else { ! 145: pgrp->pg_session = p->p_session; ! 146: pgrp->pg_session->s_count++; ! 147: } ! 148: pgrp->pg_id = pgid; ! 149: pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)]; ! 150: pgrphash[n] = pgrp; ! 151: pgrp->pg_jobc = 0; ! 152: pgrp->pg_mem = NULL; ! 153: } else if (pgrp == p->p_pgrp) ! 154: return; ! 155: ! 156: /* ! 157: * Adjust eligibility of affected pgrps to participate in job control. ! 158: * Increment eligibility counts before decrementing, otherwise we ! 159: * could reach 0 spuriously during the first call. ! 160: */ ! 161: fixjobc(p, pgrp, 1); ! 162: fixjobc(p, p->p_pgrp, 0); ! 163: ! 164: /* ! 165: * unlink p from old process group ! 166: */ ! 167: for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) ! 168: if (*pp == p) { ! 169: *pp = p->p_pgrpnxt; ! 170: goto done; ! 171: } ! 172: panic("enterpgrp: can't find p on old pgrp"); ! 173: done: ! 174: /* ! 175: * delete old if empty ! 176: */ ! 177: if (p->p_pgrp->pg_mem == 0) ! 178: pgdelete(p->p_pgrp); ! 179: /* ! 180: * link into new one ! 181: */ ! 182: p->p_pgrp = pgrp; ! 183: p->p_pgrpnxt = pgrp->pg_mem; ! 184: pgrp->pg_mem = p; ! 185: } ! 186: ! 187: /* ! 188: * remove process from process group ! 189: */ ! 190: leavepgrp(p) ! 191: register struct proc *p; ! 192: { ! 193: register struct proc **pp = &p->p_pgrp->pg_mem; ! 194: ! 195: for (; *pp; pp = &(*pp)->p_pgrpnxt) ! 196: if (*pp == p) { ! 197: *pp = p->p_pgrpnxt; ! 198: goto done; ! 199: } ! 200: panic("leavepgrp: can't find p in pgrp"); ! 201: done: ! 202: if (!p->p_pgrp->pg_mem) ! 203: pgdelete(p->p_pgrp); ! 204: p->p_pgrp = 0; ! 205: } ! 206: ! 207: /* ! 208: * delete a process group ! 209: */ ! 210: pgdelete(pgrp) ! 211: register struct pgrp *pgrp; ! 212: { ! 213: register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; ! 214: ! 215: if (pgrp->pg_session->s_ttyp != NULL && ! 216: pgrp->pg_session->s_ttyp->t_pgrp == pgrp) ! 217: pgrp->pg_session->s_ttyp->t_pgrp = NULL; ! 218: for (; *pgp; pgp = &(*pgp)->pg_hforw) ! 219: if (*pgp == pgrp) { ! 220: *pgp = pgrp->pg_hforw; ! 221: goto done; ! 222: } ! 223: panic("pgdelete: can't find pgrp on hash chain"); ! 224: done: ! 225: if (--pgrp->pg_session->s_count == 0) ! 226: FREE(pgrp->pg_session, M_SESSION); ! 227: FREE(pgrp, M_PGRP); ! 228: } ! 229: ! 230: static orphanpg(); ! 231: ! 232: /* ! 233: * Adjust pgrp jobc counters when specified process changes process group. ! 234: * We count the number of processes in each process group that "qualify" ! 235: * the group for terminal job control (those with a parent in a different ! 236: * process group of the same session). If that count reaches zero, the ! 237: * process group becomes orphaned. Check both the specified process' ! 238: * process group and that of its children. ! 239: * entering == 0 => p is leaving specified group. ! 240: * entering == 1 => p is entering specified group. ! 241: */ ! 242: fixjobc(p, pgrp, entering) ! 243: register struct proc *p; ! 244: register struct pgrp *pgrp; ! 245: int entering; ! 246: { ! 247: register struct pgrp *hispgrp; ! 248: register struct session *mysession = pgrp->pg_session; ! 249: ! 250: /* ! 251: * Check p's parent to see whether p qualifies its own process ! 252: * group; if so, adjust count for p's process group. ! 253: */ ! 254: if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && ! 255: hispgrp->pg_session == mysession) ! 256: if (entering) ! 257: pgrp->pg_jobc++; ! 258: else if (--pgrp->pg_jobc == 0) ! 259: orphanpg(pgrp); ! 260: ! 261: /* ! 262: * Check this process' children to see whether they qualify ! 263: * their process groups; if so, adjust counts for children's ! 264: * process groups. ! 265: */ ! 266: for (p = p->p_cptr; p; p = p->p_osptr) ! 267: if ((hispgrp = p->p_pgrp) != pgrp && ! 268: hispgrp->pg_session == mysession && ! 269: p->p_stat != SZOMB) ! 270: if (entering) ! 271: hispgrp->pg_jobc++; ! 272: else if (--hispgrp->pg_jobc == 0) ! 273: orphanpg(hispgrp); ! 274: } ! 275: ! 276: /* ! 277: * A process group has become orphaned; ! 278: * if there are any stopped processes in the group, ! 279: * hang-up all process in that group. ! 280: */ ! 281: static ! 282: orphanpg(pg) ! 283: struct pgrp *pg; ! 284: { ! 285: register struct proc *p; ! 286: ! 287: for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { ! 288: if (p->p_stat == SSTOP) { ! 289: for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { ! 290: psignal(p, SIGHUP); ! 291: psignal(p, SIGCONT); ! 292: } ! 293: return; ! 294: } ! 295: } ! 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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.