fdstat_sysctl.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. htop - generic/fdstat_sysctl.c
  3. (C) 2022-2023 htop dev team
  4. Released under the GNU GPLv2+, see the COPYING file
  5. in the source distribution for its full text.
  6. */
  7. #include "config.h" // IWYU pragma: keep
  8. #include "generic/fdstat_sysctl.h"
  9. #include <math.h>
  10. #include <stddef.h>
  11. #include <stdint.h>
  12. #include <sys/types.h> // Shitty FreeBSD upstream headers
  13. #include <sys/sysctl.h>
  14. static void Generic_getFileDescriptors_sysctl_internal(
  15. const char* sysctlname_maxfiles,
  16. const char* sysctlname_numfiles,
  17. size_t size_header,
  18. size_t size_entry,
  19. double* used,
  20. double* max
  21. ) {
  22. *used = NAN;
  23. *max = 65536;
  24. int max_fd, open_fd;
  25. size_t len;
  26. len = sizeof(max_fd);
  27. if (sysctlname_maxfiles && sysctlbyname(sysctlname_maxfiles, &max_fd, &len, NULL, 0) == 0) {
  28. if (max_fd) {
  29. *max = max_fd;
  30. } else {
  31. *max = NAN;
  32. }
  33. }
  34. len = sizeof(open_fd);
  35. if (sysctlname_numfiles && sysctlbyname(sysctlname_numfiles, &open_fd, &len, NULL, 0) == 0) {
  36. *used = open_fd;
  37. return;
  38. }
  39. // If no sysctl arc available, try to guess from the file table size at kern.file
  40. // The size per entry differs per OS, thus skip if we don't know:
  41. if (!size_entry)
  42. return;
  43. len = 0;
  44. if (sysctlbyname("kern.file", NULL, &len, NULL, 0) < 0)
  45. return;
  46. if (len < size_header)
  47. return;
  48. *used = (len - size_header) / size_entry;
  49. }
  50. void Generic_getFileDescriptors_sysctl(double* used, double* max) {
  51. #if defined(HTOP_DARWIN)
  52. Generic_getFileDescriptors_sysctl_internal(
  53. "kern.maxfiles", "kern.num_files", 0, 0, used, max);
  54. #elif defined(HTOP_DRAGONFLYBSD)
  55. Generic_getFileDescriptors_sysctl_internal(
  56. "kern.maxfiles", "kern.openfiles", 0, 0, used, max);
  57. #elif defined(HTOP_FREEBSD)
  58. Generic_getFileDescriptors_sysctl_internal(
  59. "kern.maxfiles", "kern.openfiles", 0, 0, used, max);
  60. #elif defined(HTOP_NETBSD)
  61. Generic_getFileDescriptors_sysctl_internal(
  62. "kern.maxfiles", NULL, 0, sizeof(struct kinfo_file), used, max);
  63. #else
  64. #error Unknown platform: Please implement proper way to query open/max file information
  65. #endif
  66. }