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

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986, 1989 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.2 ! root       33:  *     from: @(#)kern_kinfo.c  7.17 (Berkeley) 6/26/91
        !            34:  *     kern_kinfo.c,v 1.6.2.4 1993/08/06 08:11:23 cgd Exp
1.1       root       35:  */
                     36: 
                     37: #include "param.h"
1.1.1.2 ! root       38: #include "systm.h"
1.1       root       39: #include "proc.h"
                     40: #include "kinfo.h"
                     41: #include "ioctl.h"
                     42: #include "tty.h"
                     43: #include "buf.h"
                     44: #include "file.h"
                     45: 
                     46: #include "vm/vm.h"
                     47: 
                     48: #include "kinfo_proc.h"
                     49: 
                     50: #define snderr(e) { error = (e); goto release;}
                     51: extern int kinfo_doproc(), kinfo_rtable(), kinfo_vnode(), kinfo_file();
                     52: struct kinfo_lock kinfo_lock;
                     53: 
                     54: /* ARGSUSED */
1.1.1.2 ! root       55: struct getkerninfo_args {
        !            56:        int     op;
        !            57:        char    *where;
        !            58:        int     *size;
        !            59:        int     arg;
        !            60: };
        !            61: 
        !            62: int
1.1       root       63: getkerninfo(p, uap, retval)
                     64:        struct proc *p;
1.1.1.2 ! root       65:        register struct getkerninfo_args *uap;
1.1       root       66:        int *retval;
                     67: {
                     68: 
                     69:        int bufsize;            /* max size of users buffer */
                     70:        int needed, locked, (*server)(), error = 0;
                     71: 
                     72:        switch (ki_type(uap->op)) {
                     73: 
                     74:        case KINFO_PROC:
                     75:                server = kinfo_doproc;
                     76:                break;
                     77: 
                     78:        case KINFO_RT:
                     79:                server = kinfo_rtable;
                     80:                break;
                     81: 
                     82:        case KINFO_VNODE:
                     83:                server = kinfo_vnode;
                     84:                break;
                     85: 
                     86:        case KINFO_FILE:
                     87:                server = kinfo_file;
                     88:                break;
                     89: 
                     90:        default:
                     91:                error = EINVAL;
                     92:                goto done;
                     93:        }
1.1.1.2 ! root       94: 
1.1       root       95:        if (uap->where == NULL || uap->size == NULL) {
                     96:                error = (*server)(uap->op, NULL, NULL, uap->arg, &needed);
                     97:                goto done;
                     98:        }
1.1.1.2 ! root       99: 
        !           100:        if (error = copyin((caddr_t)uap->size, (caddr_t)&bufsize,
        !           101:            sizeof (bufsize)))
        !           102:                goto done;
        !           103: 
1.1       root      104:        while (kinfo_lock.kl_lock) {
                    105:                kinfo_lock.kl_want++;
1.1.1.2 ! root      106:                tsleep((caddr_t)&kinfo_lock, PRIBIO+1, "ki_lock", 0);
1.1       root      107:                kinfo_lock.kl_want--;
                    108:                kinfo_lock.kl_locked++;
                    109:        }
                    110:        kinfo_lock.kl_lock++;
                    111: 
                    112:        if (!useracc(uap->where, bufsize, B_WRITE))
                    113:                snderr(EFAULT);
                    114:        if (server != kinfo_vnode)      /* XXX */
                    115:                vslock(uap->where, bufsize);
                    116:        locked = bufsize;
                    117:        error = (*server)(uap->op, uap->where, &bufsize, uap->arg, &needed);
                    118:        if (server != kinfo_vnode)      /* XXX */
                    119:                vsunlock(uap->where, locked, B_WRITE);
                    120:        if (error == 0)
                    121:                error = copyout((caddr_t)&bufsize,
                    122:                                (caddr_t)uap->size, sizeof (bufsize));
                    123: release:
                    124:        kinfo_lock.kl_lock--;
                    125:        if (kinfo_lock.kl_want)
1.1.1.2 ! root      126:                wakeup((caddr_t)&kinfo_lock);
1.1       root      127: done:
                    128:        if (!error)
                    129:                *retval = needed;
                    130:        return (error);
                    131: }
                    132: 
                    133: /* 
                    134:  * try over estimating by 5 procs 
                    135:  */
                    136: #define KINFO_PROCSLOP (5 * sizeof (struct kinfo_proc))
                    137: 
1.1.1.2 ! root      138: int
1.1       root      139: kinfo_doproc(op, where, acopysize, arg, aneeded)
1.1.1.2 ! root      140:        int op;
1.1       root      141:        char *where;
                    142:        int *acopysize, *aneeded;
1.1.1.2 ! root      143:        int arg;
1.1       root      144: {
                    145:        register struct proc *p;
                    146:        register struct kinfo_proc *dp = (struct kinfo_proc *)where;
                    147:        register needed = 0;
                    148:        int buflen;
                    149:        int doingzomb;
                    150:        struct eproc eproc;
                    151:        int error = 0;
                    152: 
                    153:        if (where != NULL)
                    154:                buflen = *acopysize;
                    155: 
                    156:        p = allproc;
                    157:        doingzomb = 0;
                    158: again:
                    159:        for (; p != NULL; p = p->p_nxt) {
1.1.1.2 ! root      160:                /*
        !           161:                 * If process not yet fully-formed, skip it.
        !           162:                 */
        !           163:                if (p->p_stat == SIDL)
        !           164:                        continue;
1.1       root      165:                /* 
                    166:                 * TODO - make more efficient (see notes below).
                    167:                 * do by session. 
                    168:                 */
                    169:                switch (ki_op(op)) {
                    170: 
                    171:                case KINFO_PROC_PID:
                    172:                        /* could do this with just a lookup */
                    173:                        if (p->p_pid != (pid_t)arg)
                    174:                                continue;
                    175:                        break;
                    176: 
                    177:                case KINFO_PROC_PGRP:
                    178:                        /* could do this by traversing pgrp */
                    179:                        if (p->p_pgrp->pg_id != (pid_t)arg)
                    180:                                continue;
                    181:                        break;
                    182: 
                    183:                case KINFO_PROC_TTY:
                    184:                        if ((p->p_flag&SCTTY) == 0 || 
                    185:                            p->p_session->s_ttyp == NULL ||
                    186:                            p->p_session->s_ttyp->t_dev != (dev_t)arg)
                    187:                                continue;
                    188:                        break;
                    189: 
                    190:                case KINFO_PROC_UID:
                    191:                        if (p->p_ucred->cr_uid != (uid_t)arg)
                    192:                                continue;
                    193:                        break;
                    194: 
                    195:                case KINFO_PROC_RUID:
                    196:                        if (p->p_cred->p_ruid != (uid_t)arg)
                    197:                                continue;
                    198:                        break;
                    199:                }
                    200:                if (where != NULL && buflen >= sizeof (struct kinfo_proc)) {
                    201:                        fill_eproc(p, &eproc);
                    202:                        if (error = copyout((caddr_t)p, &dp->kp_proc, 
                    203:                            sizeof (struct proc)))
                    204:                                return (error);
                    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: }
                    226: 
                    227: /*
                    228:  * Fill in an eproc structure for the specified process.
                    229:  */
                    230: void
                    231: fill_eproc(p, ep)
                    232:        register struct proc *p;
                    233:        register struct eproc *ep;
                    234: {
                    235:        register struct tty *tp;
                    236: 
                    237:        ep->e_paddr = p;
                    238:        ep->e_sess = p->p_pgrp->pg_session;
                    239:        ep->e_pcred = *p->p_cred;
                    240:        ep->e_ucred = *p->p_ucred;
1.1.1.2 ! root      241:        if (p->p_stat == SIDL || p->p_stat == SZOMB)
        !           242:                bzero(&ep->e_vm, sizeof(ep->e_vm));
        !           243:        else
        !           244:                ep->e_vm = *p->p_vmspace;
1.1       root      245:        if (p->p_pptr)
                    246:                ep->e_ppid = p->p_pptr->p_pid;
                    247:        else
                    248:                ep->e_ppid = 0;
                    249:        ep->e_pgid = p->p_pgrp->pg_id;
                    250:        ep->e_jobc = p->p_pgrp->pg_jobc;
                    251:        if ((p->p_flag&SCTTY) && 
                    252:             (tp = ep->e_sess->s_ttyp)) {
                    253:                ep->e_tdev = tp->t_dev;
                    254:                ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
                    255:                ep->e_tsess = tp->t_session;
                    256:        } else
                    257:                ep->e_tdev = NODEV;
                    258:        ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;
                    259:        if (SESS_LEADER(p))
                    260:                ep->e_flag |= EPROC_SLEADER;
                    261:        if (p->p_wmesg)
                    262:                strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);
                    263:        ep->e_xsize = ep->e_xrssize = 0;
                    264:        ep->e_xccount = ep->e_xswrss = 0;
                    265: }
                    266: 
                    267: /*
                    268:  * Get file structures.
                    269:  */
1.1.1.2 ! root      270: int
1.1       root      271: kinfo_file(op, where, acopysize, arg, aneeded)
1.1.1.2 ! root      272:        int op;
1.1       root      273:        register char *where;
                    274:        int *acopysize, *aneeded;
1.1.1.2 ! root      275:        int arg;
1.1       root      276: {
                    277:        int buflen, needed, error;
                    278:        struct file *fp;
                    279:        char *start = where;
                    280: 
                    281:        if (where == NULL) {
                    282:                /*
                    283:                 * overestimate by 10 files
                    284:                 */
                    285:                *aneeded = sizeof (filehead) + 
                    286:                        (nfiles + 10) * sizeof (struct file);
                    287:                return (0);
                    288:        }
                    289:        buflen = *acopysize;
                    290:        needed = 0;
                    291: 
                    292:        /*
                    293:         * first copyout filehead
                    294:         */
                    295:        if (buflen > sizeof (filehead)) {
                    296:                if (error = copyout((caddr_t)&filehead, where,
                    297:                    sizeof (filehead)))
                    298:                        return (error);
                    299:                buflen -= sizeof (filehead);
                    300:                where += sizeof (filehead);
                    301:        }
                    302:        needed += sizeof (filehead);
                    303: 
                    304:        /*
                    305:         * followed by an array of file structures
                    306:         */
                    307:        for (fp = filehead; fp != NULL; fp = fp->f_filef) {
                    308:                if (buflen > sizeof (struct file)) {
                    309:                        if (error = copyout((caddr_t)fp, where,
                    310:                            sizeof (struct file)))
                    311:                                return (error);
                    312:                        buflen -= sizeof (struct file);
                    313:                        where += sizeof (struct file);
                    314:                }
                    315:                needed += sizeof (struct file);
                    316:        }
                    317:        *acopysize = where - start;
                    318:        *aneeded = needed;
                    319: 
                    320:        return (0);
                    321: }

unix.superglobalmegacorp.com

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