summaryrefslogtreecommitdiffstats
path: root/darwin
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2020-11-17 15:17:19 +0100
committercgzones <cgzones@googlemail.com>2020-11-23 17:00:32 +0100
commit72df9302415460908bc9018a07b68f7198e564ce (patch)
tree7664493bcee9e130c87f3b991b0a85257c3e5748 /darwin
parent6c2849ec816a9f717ec629ad0478bcb465cc8ebd (diff)
DarwinProcessList: retry getting list of all processes on ENOMEM
The process count might change between the two sysctl() calls getting the size and getting the data. Retry (3 times) in case the data-retrieval sysctl() call fails with ENOMEM. see http://mirror.informatimago.com/next/developer.apple.com/qa/qa2001/qa1123.html Related: #118
Diffstat (limited to 'darwin')
-rw-r--r--darwin/DarwinProcessList.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c
index 66f5daa6..ae1efb15 100644
--- a/darwin/DarwinProcessList.c
+++ b/darwin/DarwinProcessList.c
@@ -8,6 +8,7 @@ in the source distribution for its full text.
#include "DarwinProcessList.h"
#include <err.h>
+#include <errno.h>
#include <libproc.h>
#include <stdbool.h>
#include <stdio.h>
@@ -107,27 +108,24 @@ static struct kinfo_proc* ProcessList_getKInfoProcs(size_t* count) {
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
struct kinfo_proc* processes = NULL;
- /* Note the two calls to sysctl(). One to get length and one to get the
- * data. This -does- mean that the second call could end up with a missing
- * process entry or two.
- */
- *count = 0;
- if (sysctl(mib, 4, NULL, count, NULL, 0) < 0) {
- CRT_fatalError("Unable to get size of kproc_infos");
- }
+ for (int retry = 3; retry > 0; retry--) {
+ size_t size = 0;
+ if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
+ CRT_fatalError("Unable to get size of kproc_infos");
+ }
- processes = xMalloc(*count);
- if (processes == NULL) {
- CRT_fatalError("Out of memory for kproc_infos");
- }
+ processes = xRealloc(processes, size);
- if (sysctl(mib, 4, processes, count, NULL, 0) < 0) {
- CRT_fatalError("Unable to get kinfo_procs");
- }
+ if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
+ *count = size / sizeof(struct kinfo_proc);
+ return processes;
+ }
- *count = *count / sizeof(struct kinfo_proc);
+ if (errno != ENOMEM)
+ break;
+ }
- return processes;
+ CRT_fatalError("Unable to get kinfo_procs");
}
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {

© 2014-2024 Faster IT GmbH | imprint | privacy policy