Annotation of 43BSDReno/sys/kern/kern_proc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution is only permitted until one year after the first shipment
                      6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                      7:  * binary forms are permitted provided that: (1) source distributions retain
                      8:  * this entire copyright notice and comment, and (2) distributions including
                      9:  * binaries display the following acknowledgement:  This product includes
                     10:  * software developed by the University of California, Berkeley and its
                     11:  * contributors'' in the documentation or other materials provided with the
                     12:  * distribution and in all advertising materials mentioning features or use
                     13:  * of this software.  Neither the name of the University nor the names of
                     14:  * its contributors may be used to endorse or promote products derived from
                     15:  * this software without specific prior written permission.
                     16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     19:  *
                     20:  *     @(#)kern_proc.c 7.11 (Berkeley) 6/28/90
                     21:  */
                     22: 
                     23: #include "param.h"
                     24: #include "systm.h"
                     25: #include "map.h"
                     26: #include "user.h"
                     27: #include "kernel.h"
                     28: #include "proc.h"
                     29: #include "buf.h"
                     30: #include "seg.h"
                     31: #include "acct.h"
                     32: #include "wait.h"
                     33: #include "vm.h"
                     34: #include "text.h"
                     35: #include "file.h"
                     36: #include "../ufs/quota.h"
                     37: #include "uio.h"
                     38: #include "malloc.h"
                     39: #include "mbuf.h"
                     40: #include "ioctl.h"
                     41: #include "tty.h"
                     42: 
                     43: #include "machine/reg.h"
                     44: #include "machine/pte.h"
                     45: #include "machine/psl.h"
                     46: 
                     47: /*
                     48:  * Is p an inferior of the current process?
                     49:  */
                     50: inferior(p)
                     51:        register struct proc *p;
                     52: {
                     53:        for (; p != u.u_procp; p = p->p_pptr)
                     54:                if (p->p_ppid == 0)
                     55:                        return (0);
                     56:        return (1);
                     57: }
                     58: 
                     59: /*
                     60:  * Locate a process by number
                     61:  */
                     62: struct proc *
                     63: pfind(pid)
                     64:        register pid;
                     65: {
                     66:        register struct proc *p = pidhash[PIDHASH(pid)];
                     67: 
                     68:        for (; p; p = p->p_hash)
                     69:                if (p->p_pid == pid)
                     70:                        return (p);
                     71:        return ((struct proc *)0);
                     72: }
                     73: 
                     74: /*
                     75:  * Locate a process group by number
                     76:  */
                     77: struct pgrp *
                     78: pgfind(pgid)
                     79:        register pid_t pgid;
                     80: {
                     81:        register struct pgrp *pgrp = pgrphash[PIDHASH(pgid)];
                     82: 
                     83:        for (; pgrp; pgrp = pgrp->pg_hforw)
                     84:                if (pgrp->pg_id == pgid)
                     85:                        return (pgrp);
                     86:        return ((struct pgrp *)0);
                     87: }
                     88: 
                     89: /*
                     90:  * Move p to a new or existing process group (and session)
                     91:  */
                     92: pgmv(p, pgid, mksess)
                     93:        register struct proc *p;
                     94:        pid_t pgid;
                     95: {
                     96:        register struct pgrp *pgrp = pgfind(pgid);
                     97:        register struct proc **pp = &p->p_pgrp->pg_mem;
                     98:        register struct proc *cp;
                     99:        struct pgrp *opgrp;
                    100:        register n;
                    101: 
                    102: #ifdef DIAGNOSTIC
                    103:        if (pgrp && mksess)     /* firewalls */
                    104:                panic("pgmv: setsid into non-empty pgrp");
                    105:        if (SESS_LEADER(p))
                    106:                panic("pgmv: session leader attempted setpgrp");
                    107: #endif
                    108:        if (pgrp == NULL) {
                    109:                /*
                    110:                 * new process group
                    111:                 */
                    112: #ifdef DIAGNOSTIC
                    113:                if (p->p_pid != pgid)
                    114:                        panic("pgmv: new pgrp and pid != pgid");
                    115: #endif
                    116:                MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
                    117:                       M_WAITOK);
                    118:                if (mksess) {
                    119:                        register struct session *sess;
                    120:                        /*
                    121:                         * new session
                    122:                         */
                    123:                        MALLOC(sess, struct session *, sizeof(struct session),
                    124:                                M_SESSION, M_WAITOK);
                    125:                        sess->s_leader = p;
                    126:                        sess->s_count = 1;
                    127:                        sess->s_ttyvp = NULL;
                    128:                        sess->s_ttyp = NULL;
                    129:                        p->p_flag &= ~SCTTY;
                    130:                        pgrp->pg_session = sess;
                    131: #ifdef DIAGNOSTIC
                    132:                        if (p != u.u_procp)
                    133:                                panic("pgmv: mksession and p != u.u_procp");
                    134: #endif
                    135:                } else {
                    136:                        pgrp->pg_session = p->p_session;
                    137:                        pgrp->pg_session->s_count++;
                    138:                }
                    139:                pgrp->pg_id = pgid;
                    140:                pgrp->pg_hforw = pgrphash[n=PIDHASH(pgid)];
                    141:                pgrphash[n] = pgrp;
                    142:                pgrp->pg_jobc = 0;
                    143:                pgrp->pg_mem = NULL;
                    144:        } else if (pgrp == p->p_pgrp)
                    145:                return;
                    146:        /*
                    147:         * adjust eligibility of affected pgrps to participate in job control
                    148:         */
                    149:        fixjobc(p, 0);
                    150:        /*
                    151:         * unlink p from old process group
                    152:         */
                    153:        for (; *pp; pp = &(*pp)->p_pgrpnxt)
                    154:                if (*pp == p) {
                    155:                        *pp = p->p_pgrpnxt;
                    156:                        goto done;
                    157:                }
                    158:        panic("pgmv: can't find p on old pgrp");
                    159: done:
                    160:        /*
                    161:         * link into new one
                    162:         */
                    163:        p->p_pgrpnxt = pgrp->pg_mem;
                    164:        pgrp->pg_mem = p;
                    165:        opgrp = p->p_pgrp;
                    166:        p->p_pgrp = pgrp;
                    167:        /*
                    168:         * adjust eligibility of affected pgrps to participate in job control
                    169:         */
                    170:        fixjobc(p, 1);
                    171:        /*
                    172:         * delete old if empty
                    173:         */
                    174:        if (!opgrp->pg_mem)
                    175:                pgdelete(opgrp);
                    176: }
                    177: 
                    178: /*
                    179:  * remove process from process group
                    180:  */
                    181: pgrm(p)
                    182:        register struct proc *p;
                    183: {
                    184:        register struct proc **pp = &p->p_pgrp->pg_mem;
                    185: 
                    186:        for (; *pp; pp = &(*pp)->p_pgrpnxt)
                    187:                if (*pp == p) {
                    188:                        *pp = p->p_pgrpnxt;
                    189:                        goto done;
                    190:                }
                    191:        panic("pgrm: can't find p in pgrp");
                    192: done:
                    193:        if (!p->p_pgrp->pg_mem)
                    194:                pgdelete(p->p_pgrp);
                    195:        p->p_pgrp = 0;
                    196: }
                    197: 
                    198: /*
                    199:  * delete a process group
                    200:  */
                    201: pgdelete(pgrp)
                    202:        register struct pgrp *pgrp;
                    203: {
                    204:        register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
                    205: 
                    206:        if (pgrp->pg_session->s_ttyp != NULL && 
                    207:            pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
                    208:                pgrp->pg_session->s_ttyp->t_pgrp = NULL;
                    209:        for (; *pgp; pgp = &(*pgp)->pg_hforw)
                    210:                if (*pgp == pgrp) {
                    211:                        *pgp = pgrp->pg_hforw;
                    212:                        goto done;
                    213:                }
                    214:        panic("pgdelete: can't find pgrp on hash chain");
                    215: done:
                    216:        if (--pgrp->pg_session->s_count == 0)
                    217:                FREE(pgrp->pg_session, M_SESSION);
                    218:        FREE(pgrp, M_PGRP);
                    219: }
                    220: 
                    221: /*
                    222:  * Adjust pgrp jobc counter.
                    223:  * flag == 0 => p is leaving current state.
                    224:  * flag == 1 => p is entering current state.
                    225:  */
                    226: fixjobc(p, flag)
                    227:        register struct proc *p;
                    228:        register flag;
                    229: {
                    230:        register struct pgrp *mypgrp = p->p_pgrp, *hispgrp;
                    231:        register struct session *mysession = mypgrp->pg_session;
                    232:        register struct proc *qp;
                    233: 
                    234:        if ((hispgrp = p->p_pptr->p_pgrp) != mypgrp &&
                    235:            hispgrp->pg_session == mysession)
                    236:                if (flag)
                    237:                        mypgrp->pg_jobc++;
                    238:                else if (--mypgrp->pg_jobc == 0) {
                    239:                        int deliver = 0;
                    240: 
                    241:                        sigstopped:
                    242:                        for (qp = mypgrp->pg_mem; qp != NULL; 
                    243:                             qp = qp->p_pgrpnxt)
                    244:                                if (deliver) {
                    245:                                        psignal(qp, SIGHUP);
                    246:                                        psignal(qp, SIGCONT);
                    247:                                } else if (qp->p_stat == SSTOP) {
                    248:                                        deliver++;
                    249:                                        goto sigstopped;
                    250:                                }
                    251:                }
                    252: 
                    253:        for (p = p->p_cptr; p != NULL; p = p->p_osptr)
                    254:                if ((hispgrp = p->p_pgrp) != mypgrp &&
                    255:                    hispgrp->pg_session == mysession &&
                    256:                    p->p_stat != SZOMB)
                    257:                        if (flag)
                    258:                                hispgrp->pg_jobc++;
                    259:                        else if (--hispgrp->pg_jobc == 0) {
                    260:                                int deliver = 0;
                    261: 
                    262:                                sigstopped2:
                    263:                                for (qp = hispgrp->pg_mem; qp != NULL; 
                    264:                                     qp = qp->p_pgrpnxt)
                    265:                                        if (deliver) {
                    266:                                                psignal(qp, SIGHUP);
                    267:                                                psignal(qp, SIGCONT);
                    268:                                        } else if (qp->p_stat == SSTOP) {
                    269:                                                deliver++;
                    270:                                                goto sigstopped2;
                    271:                                        }
                    272:                        }
                    273: }
                    274:                                
                    275: /*
                    276:  * init the process queues
                    277:  */
                    278: pqinit()
                    279: {
                    280:        register struct proc *p;
                    281: 
                    282:        /*
                    283:         * most procs are initially on freequeue
                    284:         *      nb: we place them there in their "natural" order.
                    285:         */
                    286: 
                    287:        freeproc = NULL;
                    288:        for (p = procNPROC; --p > proc; freeproc = p)
                    289:                p->p_nxt = freeproc;
                    290: 
                    291:        /*
                    292:         * but proc[0] is special ...
                    293:         */
                    294: 
                    295:        allproc = p;
                    296:        p->p_nxt = NULL;
                    297:        p->p_prev = &allproc;
                    298: 
                    299:        zombproc = NULL;
                    300: }
                    301: 
                    302: #ifdef debug
                    303: /* DEBUG */
                    304: pgrpdump()
                    305: {
                    306:        register struct pgrp *pgrp;
                    307:        register struct proc *p;
                    308:        register i;
                    309: 
                    310:        for (i=0; i<PIDHSZ; i++) {
                    311:                if (pgrphash[i]) {
                    312:                  printf("\tindx %d\n", i);
                    313:                  for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
                    314:                    printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
                    315:                        pgrp, pgrp->pg_id, pgrp->pg_session,
                    316:                        pgrp->pg_session->s_count, pgrp->pg_mem);
                    317:                    for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
                    318:                        printf("\t\tpid %d addr %x pgrp %x\n", 
                    319:                                p->p_pid, p, p->p_pgrp);
                    320:                    }
                    321:                  }
                    322: 
                    323:                }
                    324:        }
                    325: }
                    326: #endif /* debug */

unix.superglobalmegacorp.com

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