master ohmu/fastfetch-openbsd / src / detection / diskio / diskio_apple.c
ohmu  ·  2026-10-15
 1#include "diskio.h"
 2#include "common/debug.h"
 3#include "common/apple/cf_helpers.h"
 4
 5#include <IOKit/IOKitLib.h>
 6#include <IOKit/IOBSD.h>
 7#include <IOKit/storage/IOMedia.h>
 8#include <IOKit/storage/IOBlockStorageDriver.h>
 9#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
10#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
11
12const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) {
13    FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
14    if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOBlockStorageDriverClass), &iterator) != KERN_SUCCESS) {
15        FF_DEBUG("IOServiceGetMatchingServices() failed");
16        return "IOServiceGetMatchingServices() failed";
17    }
18
19    io_registry_entry_t registryEntry;
20    while ((registryEntry = IOIteratorNext(iterator)) != IO_OBJECT_NULL) {
21        FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = registryEntry;
22
23        FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryMedia = IO_OBJECT_NULL;
24        if (IORegistryEntryGetChildEntry(entryDriver, kIOServicePlane, &entryMedia) != KERN_SUCCESS) {
25            continue;
26        }
27
28        io_name_t deviceName;
29        if (IORegistryEntryGetName(entryMedia, deviceName) != KERN_SUCCESS) {
30            continue;
31        }
32
33        if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0) {
34            continue;
35        }
36
37        FF_CFTYPE_AUTO_RELEASE CFDictionaryRef statistics = IORegistryEntryCreateCFProperty(entryDriver, CFSTR(kIOBlockStorageDriverStatisticsKey), kCFAllocatorDefault, kNilOptions);
38        if (!statistics) {
39            continue;
40        }
41
42        FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result);
43        ffStrbufInitS(&device->name, deviceName);
44        ffStrbufInit(&device->devPath);
45
46        ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
47        ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
48        ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey), (int64_t*) &device->readCount);
49        ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey), (int64_t*) &device->writeCount);
50
51        FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryMedia, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
52        if (bsdName) {
53            ffCfStrGetString(bsdName, &device->devPath);
54            ffStrbufPrependS(&device->devPath, "/dev/");
55        }
56    }
57
58    return nullptr;
59}