summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libkvm/kvm.c7
-rw-r--r--lib/libkvm/kvm_file2.c77
2 files changed, 44 insertions, 40 deletions
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
index a261ce4ff82..f784b5f013f 100644
--- a/lib/libkvm/kvm.c
+++ b/lib/libkvm/kvm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm.c,v 1.56 2015/09/04 02:55:09 dlg Exp $ */
+/* $OpenBSD: kvm.c,v 1.57 2015/09/04 02:58:14 dlg Exp $ */
/* $NetBSD: kvm.c,v 1.43 1996/05/05 04:31:59 gwr Exp $ */
/*-
@@ -183,7 +183,7 @@ _kvm_open(kvm_t *kd, const char *uf, const char *mf, const char *sf,
kd->swfd = -1;
kd->nlfd = -1;
kd->alive = 0;
- kd->filebase = 0;
+ kd->filebase = NULL;
kd->procbase = 0;
kd->nbpg = getpagesize();
kd->swapspc = 0;
@@ -653,8 +653,7 @@ kvm_close(kvm_t *kd)
free((void *)kd->cpu_data);
if (kd->kcore_hdr != NULL)
free((void *)kd->kcore_hdr);
- if (kd->filebase != 0)
- free((void *)kd->filebase);
+ free(kd->filebase);
if (kd->procbase != 0)
free((void *)kd->procbase);
if (kd->swapspc != 0)
diff --git a/lib/libkvm/kvm_file2.c b/lib/libkvm/kvm_file2.c
index 04912bf2562..669a7d4ae77 100644
--- a/lib/libkvm/kvm_file2.c
+++ b/lib/libkvm/kvm_file2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_file2.c,v 1.46 2015/08/28 04:38:47 guenther Exp $ */
+/* $OpenBSD: kvm_file2.c,v 1.47 2015/09/04 02:58:14 dlg Exp $ */
/*
* Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -114,6 +114,7 @@
#include <string.h>
#include <unistd.h>
#include <limits.h>
+#include <errno.h>
#include "kvm_private.h"
#include "kvm_file.h"
@@ -132,44 +133,46 @@ struct kinfo_file *
kvm_getfiles(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
{
int mib[6], rv;
+ void *filebase;
size_t size;
- if (kd->filebase != NULL) {
- free(kd->filebase);
- /*
- * Clear this pointer in case this call fails. Otherwise,
- * kvm_close() will free it again.
- */
- kd->filebase = 0;
- }
-
if (ISALIVE(kd)) {
mib[0] = CTL_KERN;
mib[1] = KERN_FILE;
mib[2] = op;
mib[3] = arg;
mib[4] = esize;
- mib[5] = 0;
-
- /* find size and alloc buffer */
- rv = sysctl(mib, 6, NULL, &size, NULL, 0);
- if (rv == -1) {
- if (kd->vmfd != -1)
- goto deadway;
- _kvm_syserr(kd, kd->program, "kvm_getfiles");
- return (NULL);
- }
- kd->filebase = _kvm_malloc(kd, size);
- if (kd->filebase == NULL)
- return (NULL);
- /* get actual data */
- mib[5] = size / esize;
- rv = sysctl(mib, 6, kd->filebase, &size, NULL, 0);
- if (rv == -1) {
- _kvm_syserr(kd, kd->program, "kvm_getfiles");
- return (NULL);
- }
+ do {
+ mib[5] = 0;
+
+ /* find size and alloc buffer */
+ rv = sysctl(mib, 6, NULL, &size, NULL, 0);
+ if (rv == -1) {
+ if (kd->vmfd != -1)
+ goto deadway;
+ _kvm_syserr(kd, kd->program, "kvm_getfiles");
+ return (NULL);
+ }
+
+ size += size / 8; /* add ~10% */
+
+ filebase = _kvm_realloc(kd, kd->filebase, size);
+ if (filebase == NULL)
+ return (NULL);
+
+ kd->filebase = filebase;
+
+ /* get actual data */
+ mib[5] = size / esize;
+ rv = sysctl(mib, 6, kd->filebase, &size, NULL, 0);
+ if (rv == -1 && errno != ENOMEM) {
+ _kvm_syserr(kd, kd->program,
+ "kvm_getfiles");
+ return (NULL);
+ }
+ } while (rv == -1);
+
*cnt = size / esize;
return (kd->filebase);
} else {
@@ -224,10 +227,11 @@ kvm_deadfile_byfile(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
_kvm_err(kd, kd->program, "can't read nfiles");
return (NULL);
}
- where = _kvm_reallocarray(kd, NULL, nfiles, esize);
- kd->filebase = (void *)where;
- if (kd->filebase == NULL)
+ where = _kvm_reallocarray(kd, kd->filebase, nfiles, esize);
+ if (where == NULL)
return (NULL);
+
+ kd->filebase = (void *)where;
buflen = nfiles * esize;
for (fp = LIST_FIRST(&filehead);
@@ -301,10 +305,11 @@ kvm_deadfile_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
return (NULL);
}
/* this may be more room than we need but counting is expensive */
- where = _kvm_reallocarray(kd, NULL, nfiles + 10, esize);
- kd->filebase = (void *)where;
- if (kd->filebase == NULL)
+ where = _kvm_reallocarray(kd, kd->filebase, nfiles + 10, esize);
+ if (where == NULL)
return (NULL);
+
+ kd->filebase = (void *)where;
buflen = (nfiles + 10) * esize;
for (pr = LIST_FIRST(&allprocess);