diff options
author | trociny <trociny@FreeBSD.org> | 2012-02-01 18:02:13 +0000 |
---|---|---|
committer | trociny <trociny@FreeBSD.org> | 2012-02-01 18:02:13 +0000 |
commit | bd849a2aadb65525a867b63fadacf22c044935d2 (patch) | |
tree | 06be821c0871e22720f31da0e3845ca84840fa73 | |
parent | 8685a56d47f2075e9208beb1818b857cfbacc06d (diff) | |
download | FreeBSD-src-bd849a2aadb65525a867b63fadacf22c044935d2.zip FreeBSD-src-bd849a2aadb65525a867b63fadacf22c044935d2.tar.gz |
Try to avoid ambiguity when sysctl returns ENOMEM additionally
checking the returned oldlen: when ENOMEM is due to the supplied
buffer being too short the return oldlen is equal to buffer size.
Without this additional check kvm_getprocs() gets stuck in loop if the
returned ENOMEM was due the exceeded memorylocked limit. This is
easily can be observed running `limits -l 1k top'.
Submitted by: Andrey Zonov <andrey zonov org>
MFC after: 1 week
-rw-r--r-- | lib/libkvm/kvm_proc.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c index dcf034c..8fc415c 100644 --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -474,7 +474,7 @@ struct kinfo_proc * kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt) { int mib[4], st, nprocs; - size_t size; + size_t size, osize; int temp_op; if (kd->procbase != 0) { @@ -524,10 +524,11 @@ kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt) _kvm_realloc(kd, kd->procbase, size); if (kd->procbase == 0) return (0); + osize = size; st = sysctl(mib, temp_op == KERN_PROC_ALL || temp_op == KERN_PROC_PROC ? 3 : 4, kd->procbase, &size, NULL, 0); - } while (st == -1 && errno == ENOMEM); + } while (st == -1 && errno == ENOMEM && size == osize); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); |