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

unix.superglobalmegacorp.com

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