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

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

unix.superglobalmegacorp.com

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