diff options
author | jhb <jhb@FreeBSD.org> | 2013-06-11 20:00:49 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2013-06-11 20:00:49 +0000 |
commit | a2ac4ba7024e6bb66be0b19455de2e2f5b17962e (patch) | |
tree | bba8b36eba6623773eb0ece22c632cda897a846c /lib/libprocstat/libprocstat.c | |
parent | 46c768b6a7fd9d51fc2b9385b56f30e852d00811 (diff) | |
download | FreeBSD-src-a2ac4ba7024e6bb66be0b19455de2e2f5b17962e.zip FreeBSD-src-a2ac4ba7024e6bb66be0b19455de2e2f5b17962e.tar.gz |
Borrow the algorithm from kvm_getprocs() to fix procstat_getprocs() to
handle the case where the process tables grows in between the calls to
fetch the size and fetch the table.
MFC after: 1 week
Diffstat (limited to 'lib/libprocstat/libprocstat.c')
-rw-r--r-- | lib/libprocstat/libprocstat.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index cd38018..7626c19 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -253,7 +253,7 @@ procstat_getprocs(struct procstat *procstat, int what, int arg, unsigned int *count) { struct kinfo_proc *p0, *p; - size_t len; + size_t len, olen; int name[4]; int cnt; int error; @@ -290,12 +290,16 @@ procstat_getprocs(struct procstat *procstat, int what, int arg, warnx("no processes?"); goto fail; } - p = malloc(len); - if (p == NULL) { - warnx("malloc(%zu)", len); - goto fail; - } - error = sysctl(name, 4, p, &len, NULL, 0); + do { + len += len / 10; + p = reallocf(p, len); + if (p == NULL) { + warnx("reallocf(%zu)", len); + goto fail; + } + olen = len; + error = sysctl(name, 4, p, &len, NULL, 0); + } while (error < 0 && errno == ENOMEM && olen == len); if (error < 0 && errno != EPERM) { warn("sysctl(kern.proc)"); goto fail; |