Annotation of 43BSDReno/sys/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 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.