Annotation of Net2/kern/kern_proc.c, revision 1.1.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.