Annotation of 43BSDReno/sys/kern/kern_kinfo.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_kinfo.c        7.11 (Berkeley) 6/28/90
        !            21:  */
        !            22: 
        !            23: #include "param.h"
        !            24: #include "user.h"
        !            25: #include "proc.h"
        !            26: #include "text.h"
        !            27: #include "kinfo.h"
        !            28: #include "vm.h"
        !            29: #include "ioctl.h"
        !            30: #include "tty.h"
        !            31: #include "buf.h"
        !            32: 
        !            33: 
        !            34: #define snderr(e) { error = (e); goto release;}
        !            35: extern int kinfo_doproc(), kinfo_rtable(), kinfo_vnode();
        !            36: struct kinfo_lock kinfo_lock;
        !            37: 
        !            38: /* ARGSUSED */
        !            39: getkerninfo(p, uap, retval)
        !            40:        struct proc *p;
        !            41:        register struct args {
        !            42:                int     op;
        !            43:                char    *where;
        !            44:                int     *size;
        !            45:                int     arg;
        !            46:        } *uap;
        !            47:        int *retval;
        !            48: {
        !            49: 
        !            50:        int     bufsize,        /* max size of users buffer */
        !            51:                needed, locked, (*server)(), error = 0;
        !            52: 
        !            53:        if (error = copyin((caddr_t)uap->size,
        !            54:                                (caddr_t)&bufsize, sizeof (bufsize)))
        !            55:                goto done;
        !            56: 
        !            57:        switch (ki_type(uap->op)) {
        !            58: 
        !            59:        case KINFO_PROC:
        !            60:                server = kinfo_doproc;
        !            61:                break;
        !            62: 
        !            63:        case KINFO_RT:
        !            64:                server = kinfo_rtable;
        !            65:                break;
        !            66: 
        !            67:        case KINFO_VNODE:
        !            68:                server = kinfo_vnode;
        !            69:                break;
        !            70: 
        !            71:        default:
        !            72:                error = EINVAL;
        !            73:                goto done;
        !            74:        }
        !            75:        if (uap->where == NULL || uap->size == NULL) {
        !            76:                error = (*server)(uap->op, NULL, NULL, uap->arg, &needed);
        !            77:                goto done;
        !            78:        }
        !            79:        while (kinfo_lock.kl_lock) {
        !            80:                kinfo_lock.kl_want++;
        !            81:                sleep(&kinfo_lock, PRIBIO+1);
        !            82:                kinfo_lock.kl_want--;
        !            83:                kinfo_lock.kl_locked++;
        !            84:        }
        !            85:        kinfo_lock.kl_lock++;
        !            86: 
        !            87:        if (!useracc(uap->where, bufsize, B_WRITE))
        !            88:                snderr(EFAULT);
        !            89:        /*
        !            90:         * lock down target pages - NEED DEADLOCK AVOIDANCE
        !            91:         */
        !            92:        if (bufsize > ((int)ptob(freemem) - (20 * 1024)))       /* XXX */
        !            93:                snderr(ENOMEM);
        !            94:        if (server != kinfo_vnode)      /* XXX */
        !            95:                vslock(uap->where, bufsize);
        !            96:        locked = bufsize;
        !            97:        error = (*server)(uap->op, uap->where, &bufsize, uap->arg, &needed);
        !            98:        if (server != kinfo_vnode)      /* XXX */
        !            99:                vsunlock(uap->where, locked, B_WRITE);
        !           100:        if (error == 0)
        !           101:                error = copyout((caddr_t)&bufsize,
        !           102:                                (caddr_t)uap->size, sizeof (bufsize));
        !           103: release:
        !           104:        kinfo_lock.kl_lock--;
        !           105:        if (kinfo_lock.kl_want)
        !           106:                wakeup(&kinfo_lock);
        !           107: done:
        !           108:        if (!error)
        !           109:                *retval = needed;
        !           110:        return (error);
        !           111: }
        !           112: 
        !           113: /* 
        !           114:  * try over estimating by 5 procs 
        !           115:  */
        !           116: #define KINFO_PROCSLOP (5 * sizeof (struct kinfo_proc))
        !           117: 
        !           118: kinfo_doproc(op, where, acopysize, arg, aneeded)
        !           119:        char *where;
        !           120:        int *acopysize, *aneeded;
        !           121: {
        !           122:        register struct proc *p;
        !           123:        register struct kinfo_proc *dp = (struct kinfo_proc *)where;
        !           124:        register needed = 0;
        !           125:        int buflen;
        !           126:        int doingzomb;
        !           127:        struct eproc eproc;
        !           128:        int error = 0;
        !           129: 
        !           130:        if (where != NULL)
        !           131:                buflen = *acopysize;
        !           132: 
        !           133:        p = allproc;
        !           134:        doingzomb = 0;
        !           135: again:
        !           136:        for (; p != NULL; p = p->p_nxt) {
        !           137:                /* 
        !           138:                 * TODO - make more efficient (see notes below).
        !           139:                 * do by session. 
        !           140:                 */
        !           141:                switch (ki_op(op)) {
        !           142: 
        !           143:                case KINFO_PROC_PID:
        !           144:                        /* could do this with just a lookup */
        !           145:                        if (p->p_pid != (pid_t)arg)
        !           146:                                continue;
        !           147:                        break;
        !           148: 
        !           149:                case KINFO_PROC_PGRP:
        !           150:                        /* could do this by traversing pgrp */
        !           151:                        if (p->p_pgrp->pg_id != (pid_t)arg)
        !           152:                                continue;
        !           153:                        break;
        !           154: 
        !           155:                case KINFO_PROC_TTY:
        !           156:                        if ((p->p_flag&SCTTY) == 0 || 
        !           157:                            p->p_session->s_ttyp == NULL ||
        !           158:                            p->p_session->s_ttyp->t_dev != (dev_t)arg)
        !           159:                                continue;
        !           160:                        break;
        !           161: 
        !           162:                case KINFO_PROC_UID:
        !           163:                        if (p->p_uid != (uid_t)arg)
        !           164:                                continue;
        !           165:                        break;
        !           166: 
        !           167:                case KINFO_PROC_RUID:
        !           168:                        if (p->p_ruid != (uid_t)arg)
        !           169:                                continue;
        !           170:                        break;
        !           171:                }
        !           172:                if (where != NULL && buflen >= sizeof (struct kinfo_proc)) {
        !           173:                        register struct text *txt;
        !           174:                        register struct tty *tp;
        !           175: 
        !           176:                        if (error = copyout((caddr_t)p, &dp->kp_proc, 
        !           177:                            sizeof (struct proc)))
        !           178:                                return (error);
        !           179:                        eproc.e_paddr = p;
        !           180:                        eproc.e_sess = p->p_pgrp->pg_session;
        !           181:                        eproc.e_pgid = p->p_pgrp->pg_id;
        !           182:                        eproc.e_jobc = p->p_pgrp->pg_jobc;
        !           183:                        if ((p->p_flag&SCTTY) && 
        !           184:                             (tp = eproc.e_sess->s_ttyp)) {
        !           185:                                eproc.e_tdev = tp->t_dev;
        !           186:                                eproc.e_tpgid = tp->t_pgrp ? 
        !           187:                                        tp->t_pgrp->pg_id : -1;
        !           188:                                eproc.e_tsess = tp->t_session;
        !           189:                        } else
        !           190:                                eproc.e_tdev = NODEV;
        !           191:                        eproc.e_flag = eproc.e_sess->s_ttyvp ? EPROC_CTTY : 0;
        !           192:                        if (SESS_LEADER(p))
        !           193:                                eproc.e_flag |= EPROC_SLEADER;
        !           194:                        if (p->p_wmesg)
        !           195:                                strncpy(eproc.e_wmesg, p->p_wmesg, WMESGLEN);
        !           196:                        if (txt = p->p_textp) {
        !           197:                                eproc.e_xsize = txt->x_size;
        !           198:                                eproc.e_xrssize = txt->x_rssize;
        !           199:                                eproc.e_xccount = txt->x_ccount;
        !           200:                                eproc.e_xswrss = txt->x_swrss;
        !           201:                        } else {
        !           202:                                eproc.e_xsize = eproc.e_xrssize =
        !           203:                                  eproc.e_xccount =  eproc.e_xswrss = 0;
        !           204:                        }
        !           205:                        if (error = copyout((caddr_t)&eproc, &dp->kp_eproc, 
        !           206:                            sizeof (eproc)))
        !           207:                                return (error);
        !           208:                        dp++;
        !           209:                        buflen -= sizeof (struct kinfo_proc);
        !           210:                }
        !           211:                needed += sizeof (struct kinfo_proc);
        !           212:        }
        !           213:        if (doingzomb == 0) {
        !           214:                p = zombproc;
        !           215:                doingzomb++;
        !           216:                goto again;
        !           217:        }
        !           218:        if (where != NULL)
        !           219:                *acopysize = (caddr_t)dp - where;
        !           220:        else
        !           221:                needed += KINFO_PROCSLOP;
        !           222:        *aneeded = needed;
        !           223: 
        !           224:        return (0);
        !           225: }

unix.superglobalmegacorp.com

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