Change the kernel dev_t, representing a pointer to a specinfo structure,
[dragonfly.git] / lib / libkvm / kvm_proc.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1989, 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software developed by the Computer Systems
6 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
7 * BG 91-66 and contributed to Berkeley.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * $FreeBSD: src/lib/libkvm/kvm_proc.c,v 1.25.2.3 2002/08/24 07:27:46 kris Exp $
b13267a5 38 * $DragonFly: src/lib/libkvm/kvm_proc.c,v 1.8 2006/09/10 01:26:26 dillon Exp $
1de703da
MD
39 *
40 * @(#)kvm_proc.c 8.3 (Berkeley) 9/23/93
984263bc
MD
41 */
42
984263bc
MD
43/*
44 * Proc traversal interface for kvm. ps and w are (probably) the exclusive
45 * users of this code, so we've factored it out into a separate module.
46 * Thus, we keep this grunge out of the other kvm applications (i.e.,
47 * most other applications are interested only in open/close/read/nlist).
48 */
49
984263bc 50#include <sys/user.h>
b13267a5
MD
51#include <sys/conf.h>
52#include <sys/param.h>
984263bc
MD
53#include <sys/proc.h>
54#include <sys/exec.h>
55#include <sys/stat.h>
56#include <sys/ioctl.h>
57#include <sys/tty.h>
58#include <sys/file.h>
59#include <stdio.h>
60#include <stdlib.h>
61#include <unistd.h>
62#include <nlist.h>
63#include <kvm.h>
64
65#include <vm/vm.h>
66#include <vm/vm_param.h>
67#include <vm/swap_pager.h>
68
69#include <sys/sysctl.h>
70
71#include <limits.h>
72#include <memory.h>
73#include <paths.h>
74
75#include "kvm_private.h"
76
77#if used
78static char *
576a9733 79kvm_readswap(kvm_t *kd, const struct proc *p, u_long va, u_long *cnt)
984263bc 80{
e5a620e1 81#if defined(__FreeBSD__) || defined(__DragonFly__)
984263bc
MD
82 /* XXX Stubbed out, our vm system is differnet */
83 _kvm_err(kd, kd->program, "kvm_readswap not implemented");
84 return(0);
e5a620e1 85#endif
984263bc
MD
86}
87#endif
88
89#define KREAD(kd, addr, obj) \
90 (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
91
92/*
93 * Read proc's from memory file into buffer bp, which has space to hold
94 * at most maxcnt procs.
95 */
96static int
576a9733
CP
97kvm_proclist(kvm_t *kd, int what, int arg, struct proc *p,
98 struct kinfo_proc *bp, int maxcnt)
984263bc 99{
576a9733 100 int cnt = 0;
984263bc
MD
101 struct eproc eproc;
102 struct pgrp pgrp;
103 struct session sess;
104 struct tty tty;
105 struct proc proc;
17c88c3a 106 struct thread thread;
984263bc 107 struct proc pproc;
b13267a5 108 struct cdev cdev;
984263bc
MD
109
110 for (; cnt < maxcnt && p != NULL; p = proc.p_list.le_next) {
111 if (KREAD(kd, (u_long)p, &proc)) {
112 _kvm_err(kd, kd->program, "can't read proc at %x", p);
113 return (-1);
114 }
17c88c3a
MD
115 if (KREAD(kd, (u_long)proc.p_thread, &thread)) {
116 _kvm_err(kd, kd->program, "can't read thread at %x",
117 proc.p_thread);
118 return (-1);
119 }
6ac7b760 120 KREAD(kd, (u_long)proc.p_ucred, &eproc.e_ucred);
984263bc
MD
121
122 switch(what) {
123
124 case KERN_PROC_PID:
125 if (proc.p_pid != (pid_t)arg)
126 continue;
127 break;
128
129 case KERN_PROC_UID:
130 if (eproc.e_ucred.cr_uid != (uid_t)arg)
131 continue;
132 break;
133
134 case KERN_PROC_RUID:
6ac7b760 135 if (eproc.e_ucred.cr_ruid != (uid_t)arg)
984263bc
MD
136 continue;
137 break;
138 }
139 /*
140 * We're going to add another proc to the set. If this
141 * will overflow the buffer, assume the reason is because
142 * nprocs (or the proc list) is corrupt and declare an error.
143 */
144 if (cnt >= maxcnt) {
145 _kvm_err(kd, kd->program, "nprocs corrupt");
146 return (-1);
147 }
148 /*
149 * gather eproc
150 */
151 eproc.e_paddr = p;
152 if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) {
153 _kvm_err(kd, kd->program, "can't read pgrp at %x",
154 proc.p_pgrp);
155 return (-1);
156 }
157 if (proc.p_oppid)
158 eproc.e_ppid = proc.p_oppid;
159 else if (proc.p_pptr) {
160 if (KREAD(kd, (u_long)proc.p_pptr, &pproc)) {
161 _kvm_err(kd, kd->program, "can't read pproc at %x",
162 proc.p_pptr);
163 return (-1);
164 }
165 eproc.e_ppid = pproc.p_pid;
166 } else
167 eproc.e_ppid = 0;
168 eproc.e_sess = pgrp.pg_session;
169 eproc.e_pgid = pgrp.pg_id;
170 eproc.e_jobc = pgrp.pg_jobc;
171 if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) {
172 _kvm_err(kd, kd->program, "can't read session at %x",
173 pgrp.pg_session);
174 return (-1);
175 }
176 (void)memcpy(eproc.e_login, sess.s_login,
177 sizeof(eproc.e_login));
178 if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) {
179 if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) {
180 _kvm_err(kd, kd->program,
181 "can't read tty at %x", sess.s_ttyp);
182 return (-1);
183 }
b13267a5
MD
184 if (tty.t_dev && tty.t_dev != NOCDEV) {
185 if (KREAD(kd, (u_long)tty.t_dev, &cdev)) {
186 eproc.e_tdev = cdev.si_udev;
187 } else {
188 eproc.e_tdev = NODEV;
189 }
190 } else {
191 eproc.e_tdev = NODEV;
192 }
984263bc
MD
193 eproc.e_tsess = tty.t_session;
194 if (tty.t_pgrp != NULL) {
195 if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
196 _kvm_err(kd, kd->program,
197 "can't read tpgrp at %x",
198 tty.t_pgrp);
199 return (-1);
200 }
201 eproc.e_tpgid = pgrp.pg_id;
202 } else
203 eproc.e_tpgid = -1;
204 } else
205 eproc.e_tdev = NODEV;
206 eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0;
207 if (sess.s_leader == p)
208 eproc.e_flag |= EPROC_SLEADER;
17c88c3a
MD
209 if (thread.td_wmesg)
210 (void)kvm_read(kd, (u_long)thread.td_wmesg,
984263bc
MD
211 eproc.e_wmesg, WMESGLEN);
212
213#ifdef sparc
214 (void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_rssize,
215 (char *)&eproc.e_vm.vm_rssize,
216 sizeof(eproc.e_vm.vm_rssize));
217 (void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_tsize,
218 (char *)&eproc.e_vm.vm_tsize,
219 3 * sizeof(eproc.e_vm.vm_rssize)); /* XXX */
220#else
221 (void)kvm_read(kd, (u_long)proc.p_vmspace,
222 (char *)&eproc.e_vm, sizeof(eproc.e_vm));
223#endif
224 eproc.e_xsize = eproc.e_xrssize = 0;
225 eproc.e_xccount = eproc.e_xswrss = 0;
226
227 switch (what) {
228
229 case KERN_PROC_PGRP:
230 if (eproc.e_pgid != (pid_t)arg)
231 continue;
232 break;
233
234 case KERN_PROC_TTY:
235 if ((proc.p_flag & P_CONTROLT) == 0 ||
236 eproc.e_tdev != (dev_t)arg)
237 continue;
238 break;
239 }
240 bcopy(&proc, &bp->kp_proc, sizeof(proc));
241 bcopy(&eproc, &bp->kp_eproc, sizeof(eproc));
242 ++bp;
243 ++cnt;
244 }
245 return (cnt);
246}
247
248/*
249 * Build proc info array by reading in proc list from a crash dump.
250 * Return number of procs read. maxcnt is the max we will read.
251 */
252static int
576a9733
CP
253kvm_deadprocs(kvm_t *kd, int what, int arg, u_long a_allproc,
254 u_long a_zombproc, int maxcnt)
984263bc 255{
576a9733
CP
256 struct kinfo_proc *bp = kd->procbase;
257 int acnt, zcnt;
984263bc
MD
258 struct proc *p;
259
260 if (KREAD(kd, a_allproc, &p)) {
261 _kvm_err(kd, kd->program, "cannot read allproc");
262 return (-1);
263 }
264 acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt);
265 if (acnt < 0)
266 return (acnt);
267
268 if (KREAD(kd, a_zombproc, &p)) {
269 _kvm_err(kd, kd->program, "cannot read zombproc");
270 return (-1);
271 }
272 zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt);
273 if (zcnt < 0)
274 zcnt = 0;
275
276 return (acnt + zcnt);
277}
278
279struct kinfo_proc *
576a9733 280kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt)
984263bc
MD
281{
282 int mib[4], st, nprocs;
283 size_t size;
284
285 if (kd->procbase != 0) {
286 free((void *)kd->procbase);
287 /*
288 * Clear this pointer in case this call fails. Otherwise,
289 * kvm_close() will free it again.
290 */
291 kd->procbase = 0;
292 }
293 if (ISALIVE(kd)) {
294 size = 0;
295 mib[0] = CTL_KERN;
296 mib[1] = KERN_PROC;
297 mib[2] = op;
298 mib[3] = arg;
299 st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4, NULL, &size, NULL, 0);
300 if (st == -1) {
301 _kvm_syserr(kd, kd->program, "kvm_getprocs");
302 return (0);
303 }
304 do {
305 size += size / 10;
306 kd->procbase = (struct kinfo_proc *)
307 _kvm_realloc(kd, kd->procbase, size);
308 if (kd->procbase == 0)
309 return (0);
310 st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4,
311 kd->procbase, &size, NULL, 0);
312 } while (st == -1 && errno == ENOMEM);
313 if (st == -1) {
314 _kvm_syserr(kd, kd->program, "kvm_getprocs");
315 return (0);
316 }
317 if (size % sizeof(struct kinfo_proc) != 0) {
318 _kvm_err(kd, kd->program,
319 "proc size mismatch (%d total, %d chunks)",
320 size, sizeof(struct kinfo_proc));
321 return (0);
322 }
323 nprocs = size / sizeof(struct kinfo_proc);
324 } else {
325 struct nlist nl[4], *p;
326
327 nl[0].n_name = "_nprocs";
328 nl[1].n_name = "_allproc";
329 nl[2].n_name = "_zombproc";
330 nl[3].n_name = 0;
331
332 if (kvm_nlist(kd, nl) != 0) {
333 for (p = nl; p->n_type != 0; ++p)
334 ;
335 _kvm_err(kd, kd->program,
336 "%s: no such symbol", p->n_name);
337 return (0);
338 }
339 if (KREAD(kd, nl[0].n_value, &nprocs)) {
340 _kvm_err(kd, kd->program, "can't read nprocs");
341 return (0);
342 }
343 size = nprocs * sizeof(struct kinfo_proc);
344 kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size);
345 if (kd->procbase == 0)
346 return (0);
347
348 nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value,
349 nl[2].n_value, nprocs);
350#ifdef notdef
351 size = nprocs * sizeof(struct kinfo_proc);
352 (void)realloc(kd->procbase, size);
353#endif
354 }
355 *cnt = nprocs;
356 return (kd->procbase);
357}
358
359void
576a9733 360_kvm_freeprocs(kvm_t *kd)
984263bc
MD
361{
362 if (kd->procbase) {
363 free(kd->procbase);
364 kd->procbase = 0;
365 }
366}
367
368void *
576a9733 369_kvm_realloc(kvm_t *kd, void *p, size_t n)
984263bc
MD
370{
371 void *np = (void *)realloc(p, n);
372
373 if (np == 0) {
374 free(p);
375 _kvm_err(kd, kd->program, "out of memory");
376 }
377 return (np);
378}
379
380#ifndef MAX
381#define MAX(a, b) ((a) > (b) ? (a) : (b))
382#endif
383
384/*
385 * Read in an argument vector from the user address space of process p.
386 * addr if the user-space base address of narg null-terminated contiguous
387 * strings. This is used to read in both the command arguments and
388 * environment strings. Read at most maxcnt characters of strings.
389 */
390static char **
576a9733 391kvm_argv(kvm_t *kd, const struct proc *p, u_long addr, int narg, int maxcnt)
984263bc 392{
576a9733
CP
393 char *np, *cp, *ep, *ap;
394 u_long oaddr = -1;
395 int len, cc;
396 char **argv;
984263bc
MD
397
398 /*
399 * Check that there aren't an unreasonable number of agruments,
400 * and that the address is in user space.
401 */
402 if (narg > 512 || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS)
403 return (0);
404
405 /*
406 * kd->argv : work space for fetching the strings from the target
407 * process's space, and is converted for returning to caller
408 */
409 if (kd->argv == 0) {
410 /*
411 * Try to avoid reallocs.
412 */
413 kd->argc = MAX(narg + 1, 32);
414 kd->argv = (char **)_kvm_malloc(kd, kd->argc *
415 sizeof(*kd->argv));
416 if (kd->argv == 0)
417 return (0);
418 } else if (narg + 1 > kd->argc) {
419 kd->argc = MAX(2 * kd->argc, narg + 1);
420 kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc *
421 sizeof(*kd->argv));
422 if (kd->argv == 0)
423 return (0);
424 }
425 /*
426 * kd->argspc : returned to user, this is where the kd->argv
427 * arrays are left pointing to the collected strings.
428 */
429 if (kd->argspc == 0) {
430 kd->argspc = (char *)_kvm_malloc(kd, PAGE_SIZE);
431 if (kd->argspc == 0)
432 return (0);
433 kd->arglen = PAGE_SIZE;
434 }
435 /*
436 * kd->argbuf : used to pull in pages from the target process.
437 * the strings are copied out of here.
438 */
439 if (kd->argbuf == 0) {
440 kd->argbuf = (char *)_kvm_malloc(kd, PAGE_SIZE);
441 if (kd->argbuf == 0)
442 return (0);
443 }
444
445 /* Pull in the target process'es argv vector */
446 cc = sizeof(char *) * narg;
447 if (kvm_uread(kd, p, addr, (char *)kd->argv, cc) != cc)
448 return (0);
449 /*
450 * ap : saved start address of string we're working on in kd->argspc
451 * np : pointer to next place to write in kd->argspc
452 * len: length of data in kd->argspc
453 * argv: pointer to the argv vector that we are hunting around the
454 * target process space for, and converting to addresses in
455 * our address space (kd->argspc).
456 */
457 ap = np = kd->argspc;
458 argv = kd->argv;
459 len = 0;
460 /*
461 * Loop over pages, filling in the argument vector.
462 * Note that the argv strings could be pointing *anywhere* in
463 * the user address space and are no longer contiguous.
464 * Note that *argv is modified when we are going to fetch a string
465 * that crosses a page boundary. We copy the next part of the string
466 * into to "np" and eventually convert the pointer.
467 */
468 while (argv < kd->argv + narg && *argv != 0) {
469
470 /* get the address that the current argv string is on */
471 addr = (u_long)*argv & ~(PAGE_SIZE - 1);
472
473 /* is it the same page as the last one? */
474 if (addr != oaddr) {
475 if (kvm_uread(kd, p, addr, kd->argbuf, PAGE_SIZE) !=
476 PAGE_SIZE)
477 return (0);
478 oaddr = addr;
479 }
480
481 /* offset within the page... kd->argbuf */
482 addr = (u_long)*argv & (PAGE_SIZE - 1);
483
484 /* cp = start of string, cc = count of chars in this chunk */
485 cp = kd->argbuf + addr;
486 cc = PAGE_SIZE - addr;
487
488 /* dont get more than asked for by user process */
489 if (maxcnt > 0 && cc > maxcnt - len)
490 cc = maxcnt - len;
491
492 /* pointer to end of string if we found it in this page */
493 ep = memchr(cp, '\0', cc);
494 if (ep != 0)
495 cc = ep - cp + 1;
496 /*
497 * at this point, cc is the count of the chars that we are
498 * going to retrieve this time. we may or may not have found
499 * the end of it. (ep points to the null if the end is known)
500 */
501
502 /* will we exceed the malloc/realloced buffer? */
503 if (len + cc > kd->arglen) {
660c873b
DR
504 int off;
505 char **pp;
506 char *op = kd->argspc;
984263bc
MD
507
508 kd->arglen *= 2;
509 kd->argspc = (char *)_kvm_realloc(kd, kd->argspc,
510 kd->arglen);
511 if (kd->argspc == 0)
512 return (0);
513 /*
514 * Adjust argv pointers in case realloc moved
515 * the string space.
516 */
517 off = kd->argspc - op;
518 for (pp = kd->argv; pp < argv; pp++)
519 *pp += off;
520 ap += off;
521 np += off;
522 }
523 /* np = where to put the next part of the string in kd->argspc*/
524 /* np is kinda redundant.. could use "kd->argspc + len" */
525 memcpy(np, cp, cc);
526 np += cc; /* inc counters */
527 len += cc;
528
529 /*
530 * if end of string found, set the *argv pointer to the
531 * saved beginning of string, and advance. argv points to
532 * somewhere in kd->argv.. This is initially relative
533 * to the target process, but when we close it off, we set
534 * it to point in our address space.
535 */
536 if (ep != 0) {
537 *argv++ = ap;
538 ap = np;
539 } else {
540 /* update the address relative to the target process */
541 *argv += cc;
542 }
543
544 if (maxcnt > 0 && len >= maxcnt) {
545 /*
546 * We're stopping prematurely. Terminate the
547 * current string.
548 */
549 if (ep == 0) {
550 *np = '\0';
551 *argv++ = ap;
552 }
553 break;
554 }
555 }
556 /* Make sure argv is terminated. */
557 *argv = 0;
558 return (kd->argv);
559}
560
561static void
576a9733 562ps_str_a(struct ps_strings *p, u_long *addr, int *n)
984263bc
MD
563{
564 *addr = (u_long)p->ps_argvstr;
565 *n = p->ps_nargvstr;
566}
567
568static void
576a9733 569ps_str_e(struct ps_strings *p, u_long *addr, int *n)
984263bc
MD
570{
571 *addr = (u_long)p->ps_envstr;
572 *n = p->ps_nenvstr;
573}
574
575/*
576 * Determine if the proc indicated by p is still active.
577 * This test is not 100% foolproof in theory, but chances of
578 * being wrong are very low.
579 */
580static int
576a9733 581proc_verify(kvm_t *kd, u_long kernp, const struct proc *p)
984263bc
MD
582{
583 struct kinfo_proc kp;
584 int mib[4];
585 size_t len;
586
587 mib[0] = CTL_KERN;
588 mib[1] = KERN_PROC;
589 mib[2] = KERN_PROC_PID;
590 mib[3] = p->p_pid;
591 len = sizeof(kp);
592 if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1)
593 return (0);
594 return (p->p_pid == kp.kp_proc.p_pid &&
595 (kp.kp_proc.p_stat != SZOMB || p->p_stat == SZOMB));
596}
597
598static char **
576a9733
CP
599kvm_doargv(kvm_t *kd, const struct kinfo_proc *kp, int nchr,
600 void (*info)(struct ps_strings *, u_long *, int *))
984263bc 601{
576a9733
CP
602 const struct proc *p = &kp->kp_proc;
603 char **ap;
984263bc
MD
604 u_long addr;
605 int cnt;
606 static struct ps_strings arginfo;
607 static u_long ps_strings;
608 size_t len;
609
610 if (ps_strings == NULL) {
611 len = sizeof(ps_strings);
612 if (sysctlbyname("kern.ps_strings", &ps_strings, &len, NULL,
613 0) == -1)
614 ps_strings = PS_STRINGS;
615 }
616
617 /*
618 * Pointers are stored at the top of the user stack.
619 */
620 if (p->p_stat == SZOMB ||
621 kvm_uread(kd, p, ps_strings, (char *)&arginfo,
622 sizeof(arginfo)) != sizeof(arginfo))
623 return (0);
624
625 (*info)(&arginfo, &addr, &cnt);
626 if (cnt == 0)
627 return (0);
628 ap = kvm_argv(kd, p, addr, cnt, nchr);
629 /*
630 * For live kernels, make sure this process didn't go away.
631 */
632 if (ap != 0 && ISALIVE(kd) &&
633 !proc_verify(kd, (u_long)kp->kp_eproc.e_paddr, p))
634 ap = 0;
635 return (ap);
636}
637
638/*
639 * Get the command args. This code is now machine independent.
640 */
641char **
576a9733 642kvm_getargv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
984263bc
MD
643{
644 int oid[4];
645 int i;
646 size_t bufsz;
647 static unsigned long buflen;
648 static char *buf, *p;
649 static char **bufp;
650 static int argc;
651
652 if (!ISALIVE(kd)) {
653 _kvm_err(kd, kd->program,
654 "cannot read user space from dead kernel");
655 return (0);
656 }
657
658 if (!buflen) {
659 bufsz = sizeof(buflen);
660 i = sysctlbyname("kern.ps_arg_cache_limit",
661 &buflen, &bufsz, NULL, 0);
662 if (i == -1) {
663 buflen = 0;
664 } else {
665 buf = malloc(buflen);
666 if (buf == NULL)
667 buflen = 0;
668 argc = 32;
669 bufp = malloc(sizeof(char *) * argc);
670 }
671 }
672 if (buf != NULL) {
673 oid[0] = CTL_KERN;
674 oid[1] = KERN_PROC;
675 oid[2] = KERN_PROC_ARGS;
676 oid[3] = kp->kp_proc.p_pid;
677 bufsz = buflen;
678 i = sysctl(oid, 4, buf, &bufsz, 0, 0);
679 if (i == 0 && bufsz > 0) {
680 i = 0;
681 p = buf;
682 do {
683 bufp[i++] = p;
684 p += strlen(p) + 1;
685 if (i >= argc) {
686 argc += argc;
687 bufp = realloc(bufp,
688 sizeof(char *) * argc);
689 }
690 } while (p < buf + bufsz);
691 bufp[i++] = 0;
692 return (bufp);
693 }
694 }
695 if (kp->kp_proc.p_flag & P_SYSTEM)
696 return (NULL);
697 return (kvm_doargv(kd, kp, nchr, ps_str_a));
698}
699
700char **
576a9733 701kvm_getenvv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
984263bc
MD
702{
703 return (kvm_doargv(kd, kp, nchr, ps_str_e));
704}
705
706/*
707 * Read from user space. The user context is given by p.
708 */
709ssize_t
576a9733 710kvm_uread(kvm_t *kd, const struct proc *p, u_long uva, char *buf, size_t len)
984263bc 711{
576a9733 712 char *cp;
984263bc
MD
713 char procfile[MAXPATHLEN];
714 ssize_t amount;
715 int fd;
716
717 if (!ISALIVE(kd)) {
718 _kvm_err(kd, kd->program,
719 "cannot read user space from dead kernel");
720 return (0);
721 }
722
723 sprintf(procfile, "/proc/%d/mem", p->p_pid);
724 fd = open(procfile, O_RDONLY, 0);
725 if (fd < 0) {
726 _kvm_err(kd, kd->program, "cannot open %s", procfile);
727 close(fd);
728 return (0);
729 }
730
731 cp = buf;
732 while (len > 0) {
733 errno = 0;
734 if (lseek(fd, (off_t)uva, 0) == -1 && errno != 0) {
735 _kvm_err(kd, kd->program, "invalid address (%x) in %s",
736 uva, procfile);
737 break;
738 }
739 amount = read(fd, cp, len);
740 if (amount < 0) {
741 _kvm_syserr(kd, kd->program, "error reading %s",
742 procfile);
743 break;
744 }
745 if (amount == 0) {
746 _kvm_err(kd, kd->program, "EOF reading %s", procfile);
747 break;
748 }
749 cp += amount;
750 uva += amount;
751 len -= amount;
752 }
753
754 close(fd);
755 return ((ssize_t)(cp - buf));
756}