Annotation of 43BSDReno/sys/kern/kern_proc.c, revision 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.