diff options
-rw-r--r-- | lib/libkvm/kvm.c | 7 | ||||
-rw-r--r-- | lib/libkvm/kvm_file2.c | 77 |
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); |