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

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 "kernel.h"
                     39: #include "proc.h"
                     40: #include "buf.h"
                     41: #include "acct.h"
                     42: #include "wait.h"
                     43: #include "file.h"
                     44: #include "../ufs/quota.h"
                     45: #include "uio.h"
                     46: #include "malloc.h"
                     47: #include "mbuf.h"
                     48: #include "ioctl.h"
                     49: #include "tty.h"
                     50: 
                     51: /*
                     52:  * Is p an inferior of the current process?
                     53:  */
                     54: inferior(p)
                     55:        register struct proc *p;
                     56: {
                     57: 
                     58:        for (; p != curproc; p = p->p_pptr)
                     59:                if (p->p_pid == 0)
                     60:                        return (0);
                     61:        return (1);
                     62: }
                     63: 
                     64: /*
                     65:  * Locate a process by number
                     66:  */
                     67: struct proc *
                     68: pfind(pid)
                     69:        register pid;
                     70: {
                     71:        register struct proc *p = pidhash[PIDHASH(pid)];
                     72: 
                     73:        for (; p; p = p->p_hash)
                     74:                if (p->p_pid == pid)
                     75:                        return (p);
                     76:        return ((struct proc *)0);
                     77: }
                     78: 
                     79: /*
                     80:  * Locate a process group by number
                     81:  */
                     82: struct pgrp *
                     83: pgfind(pgid)
                     84:        register pid_t pgid;
                     85: {
                     86:        register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
                     87: 
                     88:        for (; pgrp; pgrp = pgrp->pg_hforw)
                     89:                if (pgrp->pg_id == pgid)
                     90:                        return (pgrp);
                     91:        return ((struct pgrp *)0);
                     92: }
                     93: 
                     94: /*
                     95:  * Move p to a new or existing process group (and session)
                     96:  */
                     97: enterpgrp(p, pgid, mksess)
                     98:        register struct proc *p;
                     99:        pid_t pgid;
                    100: {
                    101:        register struct pgrp *pgrp = pgfind(pgid);
                    102:        register struct proc **pp;
                    103:        register struct proc *cp;
                    104:        int n;
                    105: 
                    106: #ifdef DIAGNOSTIC
                    107:        if (pgrp && mksess)     /* firewalls */
                    108:                panic("enterpgrp: setsid into non-empty pgrp");
                    109:        if (SESS_LEADER(p))
                    110:                panic("enterpgrp: session leader attempted setpgrp");
                    111: #endif
                    112:        if (pgrp == NULL) {
                    113:                /*
                    114:                 * new process group
                    115:                 */
                    116: #ifdef DIAGNOSTIC
                    117:                if (p->p_pid != pgid)
                    118:                        panic("enterpgrp: new pgrp and pid != pgid");
                    119: #endif
                    120:                MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
                    121:                       M_WAITOK);
                    122:                if (mksess) {
                    123:                        register struct session *sess;
                    124: 
                    125:                        /*
                    126:                         * new session
                    127:                         */
                    128:                        MALLOC(sess, struct session *, sizeof(struct session),
                    129:                                M_SESSION, M_WAITOK);
                    130:                        sess->s_leader = p;
                    131:                        sess->s_count = 1;
                    132:                        sess->s_ttyvp = NULL;
                    133:                        sess->s_ttyp = NULL;
                    134:                        bcopy(p->p_session->s_login, sess->s_login,
                    135:                            sizeof(sess->s_login));
                    136:                        p->p_flag &= ~SCTTY;
                    137:                        pgrp->pg_session = sess;
                    138: #ifdef DIAGNOSTIC
                    139:                        if (p != curproc)
                    140:                                panic("enterpgrp: mksession and p != curproc");
                    141: #endif
                    142:                } else {
                    143:                        pgrp->pg_session = p->p_session;
                    144:                        pgrp->pg_session->s_count++;
                    145:                }
                    146:                pgrp->pg_id = pgid;
                    147:                pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)];
                    148:                pgrphash[n] = pgrp;
                    149:                pgrp->pg_jobc = 0;
                    150:                pgrp->pg_mem = NULL;
                    151:        } else if (pgrp == p->p_pgrp)
                    152:                return;
                    153: 
                    154:        /*
                    155:         * Adjust eligibility of affected pgrps to participate in job control.
                    156:         * Increment eligibility counts before decrementing, otherwise we
                    157:         * could reach 0 spuriously during the first call.
                    158:         */
                    159:        fixjobc(p, pgrp, 1);
                    160:        fixjobc(p, p->p_pgrp, 0);
                    161: 
                    162:        /*
                    163:         * unlink p from old process group
                    164:         */
                    165:        for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt)
                    166:                if (*pp == p) {
                    167:                        *pp = p->p_pgrpnxt;
                    168:                        goto done;
                    169:                }
                    170:        panic("enterpgrp: can't find p on old pgrp");
                    171: done:
                    172:        /*
                    173:         * delete old if empty
                    174:         */
                    175:        if (p->p_pgrp->pg_mem == 0)
                    176:                pgdelete(p->p_pgrp);
                    177:        /*
                    178:         * link into new one
                    179:         */
                    180:        p->p_pgrp = pgrp;
                    181:        p->p_pgrpnxt = pgrp->pg_mem;
                    182:        pgrp->pg_mem = p;
                    183: }
                    184: 
                    185: /*
                    186:  * remove process from process group
                    187:  */
                    188: leavepgrp(p)
                    189:        register struct proc *p;
                    190: {
                    191:        register struct proc **pp = &p->p_pgrp->pg_mem;
                    192: 
                    193:        for (; *pp; pp = &(*pp)->p_pgrpnxt)
                    194:                if (*pp == p) {
                    195:                        *pp = p->p_pgrpnxt;
                    196:                        goto done;
                    197:                }
                    198:        panic("leavepgrp: can't find p in pgrp");
                    199: done:
                    200:        if (!p->p_pgrp->pg_mem)
                    201:                pgdelete(p->p_pgrp);
                    202:        p->p_pgrp = 0;
                    203: }
                    204: 
                    205: /*
                    206:  * delete a process group
                    207:  */
                    208: pgdelete(pgrp)
                    209:        register struct pgrp *pgrp;
                    210: {
                    211:        register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
                    212: 
                    213:        if (pgrp->pg_session->s_ttyp != NULL && 
                    214:            pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
                    215:                pgrp->pg_session->s_ttyp->t_pgrp = NULL;
                    216:        for (; *pgp; pgp = &(*pgp)->pg_hforw)
                    217:                if (*pgp == pgrp) {
                    218:                        *pgp = pgrp->pg_hforw;
                    219:                        goto done;
                    220:                }
                    221:        panic("pgdelete: can't find pgrp on hash chain");
                    222: done:
                    223:        if (--pgrp->pg_session->s_count == 0)
                    224:                FREE(pgrp->pg_session, M_SESSION);
                    225:        FREE(pgrp, M_PGRP);
                    226: }
                    227: 
                    228: static orphanpg();
                    229: 
                    230: /*
                    231:  * Adjust pgrp jobc counters when specified process changes process group.
                    232:  * We count the number of processes in each process group that "qualify"
                    233:  * the group for terminal job control (those with a parent in a different
                    234:  * process group of the same session).  If that count reaches zero, the
                    235:  * process group becomes orphaned.  Check both the specified process'
                    236:  * process group and that of its children.
                    237:  * entering == 0 => p is leaving specified group.
                    238:  * entering == 1 => p is entering specified group.
                    239:  */
                    240: fixjobc(p, pgrp, entering)
                    241:        register struct proc *p;
                    242:        register struct pgrp *pgrp;
                    243:        int entering;
                    244: {
                    245:        register struct pgrp *hispgrp;
                    246:        register struct session *mysession = pgrp->pg_session;
                    247: 
                    248:        /*
                    249:         * Check p's parent to see whether p qualifies its own process
                    250:         * group; if so, adjust count for p's process group.
                    251:         */
                    252:        if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
                    253:            hispgrp->pg_session == mysession)
                    254:                if (entering)
                    255:                        pgrp->pg_jobc++;
                    256:                else if (--pgrp->pg_jobc == 0)
                    257:                        orphanpg(pgrp);
                    258: 
                    259:        /*
                    260:         * Check this process' children to see whether they qualify
                    261:         * their process groups; if so, adjust counts for children's
                    262:         * process groups.
                    263:         */
                    264:        for (p = p->p_cptr; p; p = p->p_osptr)
                    265:                if ((hispgrp = p->p_pgrp) != pgrp &&
                    266:                    hispgrp->pg_session == mysession &&
                    267:                    p->p_stat != SZOMB)
                    268:                        if (entering)
                    269:                                hispgrp->pg_jobc++;
                    270:                        else if (--hispgrp->pg_jobc == 0)
                    271:                                orphanpg(hispgrp);
                    272: }
                    273: 
                    274: /* 
                    275:  * A process group has become orphaned;
                    276:  * if there are any stopped processes in the group,
                    277:  * hang-up all process in that group.
                    278:  */
                    279: static
                    280: orphanpg(pg)
                    281:        struct pgrp *pg;
                    282: {
                    283:        register struct proc *p;
                    284: 
                    285:        for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
                    286:                if (p->p_stat == SSTOP) {
                    287:                        for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
                    288:                                psignal(p, SIGHUP);
                    289:                                psignal(p, SIGCONT);
                    290:                        }
                    291:                        return;
                    292:                }
                    293:        }
                    294: }
                    295: 
                    296: #ifdef debug
                    297: /* DEBUG */
                    298: pgrpdump()
                    299: {
                    300:        register struct pgrp *pgrp;
                    301:        register struct proc *p;
                    302:        register i;
                    303: 
                    304:        for (i=0; i<PIDHSZ; i++) {
                    305:                if (pgrphash[i]) {
                    306:                  printf("\tindx %d\n", i);
                    307:                  for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
                    308:                    printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
                    309:                        pgrp, pgrp->pg_id, pgrp->pg_session,
                    310:                        pgrp->pg_session->s_count, pgrp->pg_mem);
                    311:                    for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
                    312:                        printf("\t\tpid %d addr %x pgrp %x\n", 
                    313:                                p->p_pid, p, p->p_pgrp);
                    314:                    }
                    315:                  }
                    316: 
                    317:                }
                    318:        }
                    319: }
                    320: #endif /* debug */

unix.superglobalmegacorp.com

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