htop/generic/fdstat_sysctl.c

81 lines
2.1 KiB
C

/*
htop - generic/fdstat_sysctl.c
(C) 2022-2023 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/
#include "config.h" // IWYU pragma: keep
#include "generic/fdstat_sysctl.h"
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h> // Shitty FreeBSD upstream headers
#include <sys/sysctl.h>
static void Generic_getFileDescriptors_sysctl_internal(
const char* sysctlname_maxfiles,
const char* sysctlname_numfiles,
size_t size_header,
size_t size_entry,
double* used,
double* max
) {
*used = NAN;
*max = 65536;
int max_fd, open_fd;
size_t len;
len = sizeof(max_fd);
if (sysctlname_maxfiles && sysctlbyname(sysctlname_maxfiles, &max_fd, &len, NULL, 0) == 0) {
if (max_fd) {
*max = max_fd;
} else {
*max = NAN;
}
}
len = sizeof(open_fd);
if (sysctlname_numfiles && sysctlbyname(sysctlname_numfiles, &open_fd, &len, NULL, 0) == 0) {
*used = open_fd;
return;
}
// If no sysctl arc available, try to guess from the file table size at kern.file
// The size per entry differs per OS, thus skip if we don't know:
if (!size_entry)
return;
len = 0;
if (sysctlbyname("kern.file", NULL, &len, NULL, 0) < 0)
return;
if (len < size_header)
return;
*used = (len - size_header) / size_entry;
}
void Generic_getFileDescriptors_sysctl(double* used, double* max) {
#if defined(HTOP_DARWIN)
Generic_getFileDescriptors_sysctl_internal(
"kern.maxfiles", "kern.num_files", 0, 0, used, max);
#elif defined(HTOP_DRAGONFLYBSD)
Generic_getFileDescriptors_sysctl_internal(
"kern.maxfiles", "kern.openfiles", 0, 0, used, max);
#elif defined(HTOP_FREEBSD)
Generic_getFileDescriptors_sysctl_internal(
"kern.maxfiles", "kern.openfiles", 0, 0, used, max);
#elif defined(HTOP_NETBSD)
Generic_getFileDescriptors_sysctl_internal(
"kern.maxfiles", NULL, 0, sizeof(struct kinfo_file), used, max);
#else
#error Unknown platform: Please implement proper way to query open/max file information
#endif
}