master ohmu/fastfetch-openbsd / src / detection / processes / processes_apple.c
ohmu  ·  2026-10-15
 1#include "processes.h"
 2#include "common/debug.h"
 3#include "common/mallocHelper.h"
 4
 5#include <errno.h>
 6#include <string.h>
 7
 8#include <sys/sysctl.h>
 9#import <libproc.h>
10
11const char* ffDetectProcesses(const FFProcessesOptions* options, FFProcessesResult* result) {
12    int request[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
13    size_t length;
14
15    if (sysctl(request, ARRAY_SIZE(request), nullptr, &length, nullptr, 0) != 0) {
16        FF_DEBUG("sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL, nullptr}) failed: %s", strerror(errno));
17        return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL, nullptr}) failed";
18    }
19
20    // The process table may change between the two sysctl calls; retry with a larger buffer.
21    length += length / 8 + sizeof(struct kinfo_proc);
22    FF_AUTO_FREE struct kinfo_proc* processes = malloc(length);
23
24    if (sysctl(request, ARRAY_SIZE(request), processes, &length, nullptr, 0) != 0) {
25        FF_DEBUG("sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL, processes}) failed: %s", strerror(errno));
26        return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL, processes}) failed";
27    }
28
29    uint32_t count = (uint32_t) (length / sizeof(struct kinfo_proc));
30
31    for (uint32_t i = 0; i < count; ++i) {
32        const struct kinfo_proc* proc = &processes[i];
33        if (!options->countKprocs && (proc->kp_proc.p_flag & P_SYSTEM)) {
34            continue;
35        }
36        result->processes++;
37
38        pid_t pid = proc->kp_proc.p_pid;
39        struct proc_taskinfo taskInfo;
40        if (proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &taskInfo, sizeof(taskInfo)) == sizeof(taskInfo)) {
41            // NOTE: This fails for system processes
42            result->threads += (uint32_t) taskInfo.pti_threadnum;
43        }
44    }
45
46    return nullptr;
47}