|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.