mirror of https://github.com/xzeldon/htop.git
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
This commit is contained in:
parent
6c2849ec81
commit
72df930241
|
@ -8,6 +8,7 @@ in the source distribution for its full text.
|
||||||
#include "DarwinProcessList.h"
|
#include "DarwinProcessList.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <libproc.h>
|
#include <libproc.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.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 };
|
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
|
||||||
struct kinfo_proc* processes = NULL;
|
struct kinfo_proc* processes = NULL;
|
||||||
|
|
||||||
/* Note the two calls to sysctl(). One to get length and one to get the
|
for (int retry = 3; retry > 0; retry--) {
|
||||||
* data. This -does- mean that the second call could end up with a missing
|
size_t size = 0;
|
||||||
* process entry or two.
|
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
|
||||||
*/
|
CRT_fatalError("Unable to get size of kproc_infos");
|
||||||
*count = 0;
|
}
|
||||||
if (sysctl(mib, 4, NULL, count, NULL, 0) < 0) {
|
|
||||||
CRT_fatalError("Unable to get size of kproc_infos");
|
processes = xRealloc(processes, size);
|
||||||
|
|
||||||
|
if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
|
||||||
|
*count = size / sizeof(struct kinfo_proc);
|
||||||
|
return processes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno != ENOMEM)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
processes = xMalloc(*count);
|
CRT_fatalError("Unable to get kinfo_procs");
|
||||||
if (processes == NULL) {
|
|
||||||
CRT_fatalError("Out of memory for kproc_infos");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sysctl(mib, 4, processes, count, NULL, 0) < 0) {
|
|
||||||
CRT_fatalError("Unable to get kinfo_procs");
|
|
||||||
}
|
|
||||||
|
|
||||||
*count = *count / sizeof(struct kinfo_proc);
|
|
||||||
|
|
||||||
return processes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {
|
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {
|
||||||
|
|
Loading…
Reference in New Issue