summaryrefslogtreecommitdiff
path: root/lib/libkvm
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-09-08 15:40:33 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-09-08 15:40:33 +0000
commit0454c732bcf67fa6113e2400dc76fed6feb1872e (patch)
tree00c30b38269d07f43a65b69418619fd758d987e0 /lib/libkvm
parente5afdf5a3b8757e4198aaceb006a5149cf321670 (diff)
port the changes just made to kvm_getfiles in kvm_file2.c r1.47 to
kvm_getprocs. basically cope with the number of procs growing between when we get the size and when we get the list. ok guenther@
Diffstat (limited to 'lib/libkvm')
-rw-r--r--lib/libkvm/kvm.c7
-rw-r--r--lib/libkvm/kvm_proc2.c52
2 files changed, 30 insertions, 29 deletions
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
index f784b5f013f..d9878911ef5 100644
--- a/lib/libkvm/kvm.c
+++ b/lib/libkvm/kvm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm.c,v 1.57 2015/09/04 02:58:14 dlg Exp $ */
+/* $OpenBSD: kvm.c,v 1.58 2015/09/08 15:40:32 dlg Exp $ */
/* $NetBSD: kvm.c,v 1.43 1996/05/05 04:31:59 gwr Exp $ */
/*-
@@ -184,7 +184,7 @@ _kvm_open(kvm_t *kd, const char *uf, const char *mf, const char *sf,
kd->nlfd = -1;
kd->alive = 0;
kd->filebase = NULL;
- kd->procbase = 0;
+ kd->procbase = NULL;
kd->nbpg = getpagesize();
kd->swapspc = 0;
kd->argspc = 0;
@@ -654,8 +654,7 @@ kvm_close(kvm_t *kd)
if (kd->kcore_hdr != NULL)
free((void *)kd->kcore_hdr);
free(kd->filebase);
- if (kd->procbase != 0)
- free((void *)kd->procbase);
+ free(kd->procbase);
if (kd->swapspc != 0)
free((void *)kd->swapspc);
if (kd->argspc != 0)
diff --git a/lib/libkvm/kvm_proc2.c b/lib/libkvm/kvm_proc2.c
index 50e5521631f..52b74fe8815 100644
--- a/lib/libkvm/kvm_proc2.c
+++ b/lib/libkvm/kvm_proc2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_proc2.c,v 1.25 2014/10/15 02:03:05 deraadt Exp $ */
+/* $OpenBSD: kvm_proc2.c,v 1.26 2015/09/08 15:40:32 dlg Exp $ */
/* $NetBSD: kvm_proc.c,v 1.30 1999/03/24 05:50:50 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -95,6 +95,7 @@
#include <sys/sysctl.h>
#include <limits.h>
+#include <errno.h>
#include <db.h>
#include <paths.h>
@@ -397,20 +398,12 @@ struct kinfo_proc *
kvm_getprocs(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
{
int mib[6], st, nthreads;
+ void *procbase;
size_t size;
if ((ssize_t)esize < 0)
return (NULL);
- if (kd->procbase != NULL) {
- free(kd->procbase);
- /*
- * Clear this pointer in case this call fails. Otherwise,
- * kvm_close() will free it again.
- */
- kd->procbase = 0;
- }
-
if (ISALIVE(kd)) {
size = 0;
mib[0] = CTL_KERN;
@@ -418,22 +411,31 @@ kvm_getprocs(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
mib[2] = op;
mib[3] = arg;
mib[4] = esize;
- mib[5] = 0;
- st = sysctl(mib, 6, NULL, &size, NULL, 0);
- if (st == -1) {
- _kvm_syserr(kd, kd->program, "kvm_getprocs");
- return (NULL);
- }
- mib[5] = size / esize;
- kd->procbase = _kvm_malloc(kd, size);
- if (kd->procbase == 0)
- return (NULL);
- st = sysctl(mib, 6, kd->procbase, &size, NULL, 0);
- if (st == -1) {
- _kvm_syserr(kd, kd->program, "kvm_getprocs");
- return (NULL);
- }
+ do {
+ mib[5] = 0;
+ st = sysctl(mib, 6, NULL, &size, NULL, 0);
+ if (st == -1) {
+ _kvm_syserr(kd, kd->program, "kvm_getprocs");
+ return (NULL);
+ }
+
+ size += size / 8; /* add ~10% */
+
+ procbase = _kvm_realloc(kd, kd->procbase, size);
+ if (procbase == NULL)
+ return (NULL);
+
+ kd->procbase = procbase;
+
+ mib[5] = size / esize;
+ st = sysctl(mib, 6, kd->procbase, &size, NULL, 0);
+ if (st == -1 && errno != ENOMEM) {
+ _kvm_syserr(kd, kd->program, "kvm_getprocs");
+ return (NULL);
+ }
+ } while (st == -1);
+
nthreads = size / esize;
} else {
struct nlist nl[5];