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.. :-)
This commit is contained in:
Peter Wemm 1995-12-09 04:42:51 +00:00
parent c0072256cd
commit 77721f53be
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=12682
2 changed files with 53 additions and 35 deletions

View File

@ -57,6 +57,7 @@ struct __kvm {
int arglen; /* length of the above */
char **argv; /* (dynamic) storage for argv pointers */
int argc; /* length of above (not actual # present) */
char *argbuf; /* (dynamic) temporary storage */
/*
* Kernel virtual address translation state. This only gets filled
* in for dead kernels; otherwise, the running kernel (i.e. kmem)

View File

@ -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.