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