diff options
author | peter <peter@FreeBSD.org> | 1995-12-09 04:42:51 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1995-12-09 04:42:51 +0000 |
commit | 2e32505a556a745cfb1b3072490b507b550da5fa (patch) | |
tree | f2f4183cdba6f1c7f3d0312078ca00e799ab97b1 /lib/libkvm/kvm_proc.c | |
parent | f525350c683a3b2d7ea7efd96f6ed5f5a2cb5699 (diff) | |
download | FreeBSD-src-2e32505a556a745cfb1b3072490b507b550da5fa.zip FreeBSD-src-2e32505a556a745cfb1b3072490b507b550da5fa.tar.gz |
Updates to read the extra indirection in ps_strings. Note that any
static executables that depend on this will need to be relinked (ie: do
this before 'ps'), but the dynamic linked stuff should be OK (ie: 'w')
Obtained from: NetBSD (not much point reinventing the wheel.. :-)
Diffstat (limited to 'lib/libkvm/kvm_proc.c')
-rw-r--r-- | lib/libkvm/kvm_proc.c | 87 |
1 files changed, 52 insertions, 35 deletions
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c index 6b29d40..76bb850 100644 --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -65,6 +65,7 @@ static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93"; #include <sys/sysctl.h> #include <limits.h> +#include <memory.h> #include <db.h> #include <paths.h> @@ -361,19 +362,20 @@ _kvm_realloc(kd, p, n) /* * Read in an argument vector from the user address space of process p. - * addr is the user-space base address of narg null-terminated contiguous + * addr if the user-space base address of narg null-terminated contiguous * strings. This is used to read in both the command arguments and * environment strings. Read at most maxcnt characters of strings. */ static char ** kvm_argv(kd, p, addr, narg, maxcnt) kvm_t *kd; - struct proc *p; + const struct proc *p; register u_long addr; register int narg; register int maxcnt; { - register char *cp; + register char *np, *cp, *ep, *ap; + register u_long oaddr = -1; register int len, cc; register char **argv; @@ -381,7 +383,7 @@ kvm_argv(kd, p, addr, narg, maxcnt) * Check that there aren't an unreasonable number of agruments, * and that the address is in user space. */ - if (narg > 512 || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS) + if (narg > ARG_MAX || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS) return (0); if (kd->argv == 0) { @@ -406,17 +408,36 @@ kvm_argv(kd, p, addr, narg, maxcnt) return (0); kd->arglen = NBPG; } - cp = kd->argspc; + if (kd->argbuf == 0) { + kd->argbuf = (char *)_kvm_malloc(kd, NBPG); + if (kd->argbuf == 0) + return (0); + } + cc = sizeof(char *) * narg; + if (kvm_uread(kd, p, addr, (char *)kd->argv, cc) != cc) + return (0); + ap = np = kd->argspc; argv = kd->argv; - *argv = cp; len = 0; /* * Loop over pages, filling in the argument vector. */ - while (addr < VM_MAXUSER_ADDRESS) { - cc = NBPG - (addr & PGOFSET); + while (argv < kd->argv + narg && *argv != 0) { + addr = (u_long)*argv & ~(NBPG - 1); + if (addr != oaddr) { + if (kvm_uread(kd, p, addr, kd->argbuf, NBPG) != + NBPG) + return (0); + oaddr = addr; + } + addr = (u_long)*argv & (NBPG - 1); + cp = kd->argbuf + addr; + cc = NBPG - addr; if (maxcnt > 0 && cc > maxcnt - len) cc = maxcnt - len;; + ep = memchr(cp, '\0', cc); + if (ep != 0) + cc = ep - cp + 1; if (len + cc > kd->arglen) { register int off; register char **pp; @@ -427,45 +448,39 @@ kvm_argv(kd, p, addr, narg, maxcnt) kd->arglen); if (kd->argspc == 0) return (0); - cp = &kd->argspc[len]; /* * Adjust argv pointers in case realloc moved * the string space. */ off = kd->argspc - op; - for (pp = kd->argv; pp < argv; ++pp) + for (pp = kd->argv; pp < argv; pp++) *pp += off; + ap += off; + np += off; } - if (kvm_uread(kd, p, addr, cp, cc) != cc) - /* XXX */ - return (0); + memcpy(np, cp, cc); + np += cc; len += cc; - addr += cc; - - if (maxcnt == 0 && len > 16 * NBPG) - /* sanity */ - return (0); - - while (--cc >= 0) { - if (*cp++ == 0) { - if (--narg <= 0 || (struct ps_strings *)(addr - cc) >= PS_STRINGS) { - *++argv = 0; - return (kd->argv); + if (ep != 0) { + *argv++ = ap; + ap = np; } else - *++argv = cp; - } - } + *argv += cc; if (maxcnt > 0 && len >= maxcnt) { /* * We're stopping prematurely. Terminate the - * argv and current string. + * current string. */ - *++argv = 0; - *cp = 0; - return (kd->argv); + if (ep == 0) { + *np = '\0'; + *argv++ = ap; } + break; } - return (0); + } + /* Make sure argv is terminated. */ + *argv = 0; + return (kd->argv); } static void @@ -517,7 +532,7 @@ kvm_doargv(kd, kp, nchr, info) kvm_t *kd; const struct kinfo_proc *kp; int nchr; - int (*info)(struct ps_strings*, u_long *, int *); + void (*info)(struct ps_strings *, u_long *, int *); { register const struct proc *p = &kp->kp_proc; register char **ap; @@ -529,11 +544,13 @@ kvm_doargv(kd, kp, nchr, info) * Pointers are stored at the top of the user stack. */ if (p->p_stat == SZOMB || - kvm_uread(kd, p, USRSTACK - sizeof(arginfo) - SPARE_USRSPACE, - (char *)&arginfo, sizeof(arginfo)) != sizeof(arginfo)) + kvm_uread(kd, p, USRSTACK - sizeof(arginfo), (char *)&arginfo, + sizeof(arginfo)) != sizeof(arginfo)) return (0); (*info)(&arginfo, &addr, &cnt); + if (cnt == 0) + return (0); ap = kvm_argv(kd, p, addr, cnt, nchr); /* * For live kernels, make sure this process didn't go away. |