Annotation of Net2/kern/kern_proc.c, revision 1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.