diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2022-09-02 11:38:20 +0000 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2022-09-02 11:39:08 +0000 |
commit | c7c7bbcfc762d73a50d3cb2ad6f277dad7bb9a6b (patch) | |
tree | ecc034b178f6a9d3f89fab6ccec45e9bd018aff2 /psutil | |
parent | d2fab7c8de16b6ffbfb0faa3e832845bc1ef0df0 (diff) | |
download | psutil-c7c7bbcfc762d73a50d3cb2ad6f277dad7bb9a6b.tar.gz |
FreeBSD / pids(): increase buf size if not enough
...dynamically, in case of ENOMEM, instead of crashing.
Fixes #2093.
Diffstat (limited to 'psutil')
-rw-r--r-- | psutil/arch/freebsd/proc.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/psutil/arch/freebsd/proc.c b/psutil/arch/freebsd/proc.c index a2e130b5..214dbc48 100644 --- a/psutil/arch/freebsd/proc.c +++ b/psutil/arch/freebsd/proc.c @@ -83,6 +83,7 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) { struct kinfo_proc *buf = NULL; int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 }; size_t length = 0; + size_t max_length = 12 * 1024 * 1024; // 12MB assert(procList != NULL); assert(*procList == NULL); @@ -95,20 +96,36 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) { return 1; } - // Allocate an appropriately sized buffer based on the results - // from the previous call. - buf = malloc(length); - if (buf == NULL) { - PyErr_NoMemory(); - return 1; - } + while (1) { + // Allocate an appropriately sized buffer based on the results + // from the previous call. + buf = malloc(length); + if (buf == NULL) { + PyErr_NoMemory(); + return 1; + } - // Call sysctl again with the new buffer. - err = sysctl(name, 3, buf, &length, NULL, 0); - if (err == -1) { - PyErr_SetFromOSErrnoWithSyscall("sysctl"); - free(buf); - return 1; + // Call sysctl again with the new buffer. + err = sysctl(name, 3, buf, &length, NULL, 0); + if (err == -1) { + free(buf); + if (errno == ENOMEM) { + // Sometimes the first sysctl() suggested size is not enough, + // so we dynamically increase it until it's big enough : + // https://github.com/giampaolo/psutil/issues/2093 + psutil_debug("errno=ENOMEM, length=%zu; retrying", length); + length *= 2; + if (length < max_length) { + continue; + } + } + + PyErr_SetFromOSErrnoWithSyscall("sysctl()"); + return 1; + } + else { + break; + } } *procList = buf; |