From 2c4caf8e0d74fa9f3e50de50c115b45e5d7c0f53 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 28 Aug 2026 16:22:33 +0800 Subject: [PATCH] Top: removes realloc retries --- src/detection/top/top_apple.c | 26 +++++++++----------------- src/detection/top/top_bsd.c | 18 ++++-------------- src/detection/top/top_dbsd.c | 21 ++++++--------------- src/detection/top/top_nbsd.c | 21 ++++++--------------- 4 files changed, 25 insertions(+), 61 deletions(-) diff --git a/src/detection/top/top_apple.c b/src/detection/top/top_apple.c index 3c8250526..862431381 100644 --- a/src/detection/top/top_apple.c +++ b/src/detection/top/top_apple.c @@ -10,33 +10,25 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes) { size_t length; if (sysctl(request, ARRAY_SIZE(request), nullptr, &length, nullptr, 0) != 0) { - return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL}) failed"; + return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL, nullptr}) failed"; } // The process table may change between the two sysctl calls; retry with a larger buffer. - FF_AUTO_FREE struct kinfo_proc* processes = nullptr; - for (int attempts = 0;; ++attempts) { - length += length / 8 + sizeof(struct kinfo_proc); - struct kinfo_proc* newProcesses = (struct kinfo_proc*) realloc(processes, length); - if (!newProcesses) { - return "realloc(struct kinfo_proc[]) failed"; - } - processes = newProcesses; - if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) == 0) { - break; - } - if ((errno != ENOMEM && errno != EINVAL) || attempts >= 4) { - return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL}) failed"; - } + length += length / 8 + sizeof(struct kinfo_proc); + FF_AUTO_FREE struct kinfo_proc* processes = malloc(length); + + if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) != 0) { + return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL, processes}) failed"; } + uint32_t count = (uint32_t) (length / sizeof(struct kinfo_proc)); for (uint32_t i = 0; i < count; ++i) { const struct kinfo_proc* proc = &processes[i]; - pid_t pid = proc->kp_proc.p_pid; - if (pid <= 0) { + if (proc->kp_proc.p_flag & P_SYSTEM) { continue; } + pid_t pid = proc->kp_proc.p_pid; struct rusage_info_v2 rusage; if (proc_pid_rusage(pid, RUSAGE_INFO_V2, (rusage_info_t*) &rusage) != 0) { diff --git a/src/detection/top/top_bsd.c b/src/detection/top/top_bsd.c index 620b234b1..6c0f62018 100644 --- a/src/detection/top/top_bsd.c +++ b/src/detection/top/top_bsd.c @@ -15,20 +15,10 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes) { } // The process table may change between the two sysctl calls; retry with a larger buffer. - FF_AUTO_FREE struct kinfo_proc* processes = nullptr; - for (int attempts = 0;; ++attempts) { - length += length / 8 + sizeof(struct kinfo_proc); - struct kinfo_proc* newProcesses = (struct kinfo_proc*) realloc(processes, length); - if (!newProcesses) { - return "realloc(struct kinfo_proc[]) failed"; - } - processes = newProcesses; - if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) == 0) { - break; - } - if ((errno != ENOMEM && errno != EINVAL) || attempts >= 4) { - return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_PROC}) failed"; - } + length += length / 8 + sizeof(struct kinfo_proc); + FF_AUTO_FREE struct kinfo_proc* processes = malloc(length); + if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) != 0) { + return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_PROC}) failed"; } uint32_t count = (uint32_t) (length / sizeof(struct kinfo_proc)); diff --git a/src/detection/top/top_dbsd.c b/src/detection/top/top_dbsd.c index 1a9bbb888..858cc616d 100644 --- a/src/detection/top/top_dbsd.c +++ b/src/detection/top/top_dbsd.c @@ -11,24 +11,15 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes) { size_t length; if (sysctl(request, ARRAY_SIZE(request), nullptr, &length, nullptr, 0) != 0) { - return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL}) failed"; + return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL, nullptr}) failed"; } // The process table may change between the two sysctl calls; retry with a larger buffer. - FF_AUTO_FREE struct kinfo_proc* processes = nullptr; - for (int attempts = 0;; ++attempts) { - length += length / 8 + sizeof(struct kinfo_proc); - struct kinfo_proc* newProcesses = (struct kinfo_proc*) realloc(processes, length); - if (!newProcesses) { - return "realloc(struct kinfo_proc[]) failed"; - } - processes = newProcesses; - if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) == 0) { - break; - } - if ((errno != ENOMEM && errno != EINVAL) || attempts >= 4) { - return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL}) failed"; - } + length += length / 8 + sizeof(struct kinfo_proc); + + FF_AUTO_FREE struct kinfo_proc* processes = malloc(length); + if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) != 0) { + return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL, processes}) failed"; } uint32_t count = (uint32_t) (length / sizeof(struct kinfo_proc)); diff --git a/src/detection/top/top_nbsd.c b/src/detection/top/top_nbsd.c index 277354ed3..1bc8e6543 100644 --- a/src/detection/top/top_nbsd.c +++ b/src/detection/top/top_nbsd.c @@ -11,24 +11,15 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes) { size_t length; if (sysctl(request, ARRAY_SIZE(request), nullptr, &length, nullptr, 0) != 0) { - return "sysctl({CTL_KERN, KERN_PROC2, KERN_PROC_ALL}) failed"; + return "sysctl({CTL_KERN, KERN_PROC2, KERN_PROC_ALL, nullptr}) failed"; } // The process table may change between the two sysctl calls; retry with a larger buffer. - FF_AUTO_FREE struct kinfo_proc2* processes = nullptr; - for (int attempts = 0;; ++attempts) { - length += length / 8 + sizeof(struct kinfo_proc2); - struct kinfo_proc2* newProcesses = (struct kinfo_proc2*) realloc(processes, length); - if (!newProcesses) { - return "realloc(struct kinfo_proc2[]) failed"; - } - processes = newProcesses; - if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) == 0) { - break; - } - if ((errno != ENOMEM && errno != EINVAL) || attempts >= 4) { - return "sysctl({CTL_KERN, KERN_PROC2, KERN_PROC_ALL}) failed"; - } + length += length / 8 + sizeof(struct kinfo_proc2); + + FF_AUTO_FREE struct kinfo_proc2* processes = malloc(length); + if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) != 0) { + return "sysctl({CTL_KERN, KERN_PROC2, KERN_PROC_ALL, processes}) failed"; } uint32_t count = (uint32_t) (length / sizeof(struct kinfo_proc2));