mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
58 lines
2.1 KiB
C
58 lines
2.1 KiB
C
#include "top.h"
|
|
#include "common/mallocHelper.h"
|
|
|
|
#include <errno.h>
|
|
#include <sys/sysctl.h>
|
|
#include <libproc.h>
|
|
|
|
const char* ffTopGetProcessSnapshot(FFlist* snapshots) {
|
|
int request[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
|
|
size_t length;
|
|
|
|
if (sysctl(request, ARRAY_SIZE(request), nullptr, &length, nullptr, 0) != 0) {
|
|
return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL}) 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";
|
|
}
|
|
}
|
|
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) {
|
|
continue;
|
|
}
|
|
|
|
struct rusage_info_v2 rusage;
|
|
if (proc_pid_rusage(pid, RUSAGE_INFO_V2, (rusage_info_t*) &rusage) != 0) {
|
|
continue; // The process may have exited
|
|
}
|
|
|
|
FFTopProcessSnapshot* item = FF_LIST_ADD(FFTopProcessSnapshot, *snapshots);
|
|
ffStrbufInitS(&item->name, proc->kp_proc.p_comm);
|
|
item->pid = (uint32_t) pid;
|
|
item->cpuTime = (rusage.ri_user_time + rusage.ri_system_time) / 1000000u; // ns -> ms
|
|
item->memBytes = rusage.ri_resident_size;
|
|
item->bytesRead = rusage.ri_diskio_bytesread;
|
|
item->bytesWritten = rusage.ri_diskio_byteswritten;
|
|
item->startTime = rusage.ri_proc_start_abstime;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|