diff --git a/CHANGELOG.md b/CHANGELOG.md index 625a9e012c..849b497b4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +# 2.65.2 + +Changes: +* Memory usage calculations now exclude the ZFS ARC cache on Linux, FreeBSD, NetBSD, and SunOS. (#1995 / #2418, Memory) + * This prevents the Memory module from reporting artificially high memory usage on systems with the ZFS kmod enabled. + +Bugfixes: +* The GPU module no longer pings sleeping dedicated GPUs on dual-GPU laptops. (#2419, GPU) + * As a result, PCIe link speed detection (introduced in v2.65.0) is now only enabled in `driverSpecific` mode. +* Fixed a crash when detecting hardware codec support with the `amdgpu` driver on Linux. (#2419, Codec, Linux) + +Logos: +* Updated CachyOS_small +* Added Turkish + +# 2.65.1 + +No changes + # 2.65.0 Changes: diff --git a/CMakeLists.txt b/CMakeLists.txt index add2ab1807..810cd9d44f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.65.1 + VERSION 2.65.2 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" diff --git a/debian/changelog.tpl b/debian/changelog.tpl index 6c93660ac0..9780c230be 100644 --- a/debian/changelog.tpl +++ b/debian/changelog.tpl @@ -1,3 +1,9 @@ +fastfetch (2.65.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium + + * Update to 2.65.1 + + -- Carter Li Wed, 24 Jun 2026 14:21:06 +0800 + fastfetch (2.64.2~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium * Update to 2.64.2 diff --git a/debian/publish.sh b/debian/publish.sh index af3a1fc0d7..fde63d45b4 100755 --- a/debian/publish.sh +++ b/debian/publish.sh @@ -10,7 +10,7 @@ SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" ROOT_DIR="$(cd -- "$SCRIPT_DIR/.." >/dev/null 2>&1 && pwd)" OUT_DIR="$(dirname "$ROOT_DIR")" PPA="ppa:zhangsongcui3371/fastfetch" -CODENAMES=( jammy noble plucky questing resolute ) +CODENAMES=( jammy noble plucky questing resolute stonking ) DRY_RUN=0 if [[ -d "$OUT_DIR/build" ]]; then diff --git a/presets/examples/13.jsonc b/presets/examples/13.jsonc index b9e6164004..0cb4711c01 100644 --- a/presets/examples/13.jsonc +++ b/presets/examples/13.jsonc @@ -1,4 +1,4 @@ -// Inspired by Catnap +// Inspired by Catnap (https://github.com/iinsertNameHere/catnap) { "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", "logo": { diff --git a/presets/examples/14.jsonc b/presets/examples/14.jsonc index f7df5ce33f..b20c544775 100644 --- a/presets/examples/14.jsonc +++ b/presets/examples/14.jsonc @@ -1,4 +1,4 @@ -// Inspired by Catnap +// Inspired by Catnap (https://github.com/iinsertNameHere/catnap) { "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", "logo": { diff --git a/presets/examples/15.jsonc b/presets/examples/15.jsonc index c53b083cc5..0f49b20044 100644 --- a/presets/examples/15.jsonc +++ b/presets/examples/15.jsonc @@ -1,4 +1,4 @@ -// Inspired by Catnap +// Inspired by Catnap (https://github.com/iinsertNameHere/catnap) { "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", "logo": { diff --git a/presets/examples/16.jsonc b/presets/examples/16.jsonc index 0d12c152a5..a42112c406 100644 --- a/presets/examples/16.jsonc +++ b/presets/examples/16.jsonc @@ -1,4 +1,4 @@ -// Inspired by Catnap +// Inspired by Catnap (https://github.com/iinsertNameHere/catnap) { "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", "logo": { diff --git a/src/common/impl/settings.c b/src/common/impl/settings.c index e7d246b12b..1e1d05f357 100644 --- a/src/common/impl/settings.c +++ b/src/common/impl/settings.c @@ -391,7 +391,7 @@ int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) { } sqlite3* db; - if (data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) { + if (data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX, NULL) != SQLITE_OK) { return 0; } diff --git a/src/detection/codec/codec_linux.c b/src/detection/codec/codec_linux.c index 13639f3c96..2a2c213ca2 100644 --- a/src/detection/codec/codec_linux.c +++ b/src/detection/codec/codec_linux.c @@ -237,7 +237,7 @@ static const char* detectCodecByVaDrm(FFVAData* vaData, FFCodecOptions* options, continue; } - FF_AUTO_CLOSE_FD int fd = openat(drifd, entry->d_name, O_RDONLY | O_CLOEXEC); + FF_AUTO_CLOSE_FD int fd = openat(drifd, entry->d_name, O_RDWR | O_CLOEXEC); if (fd < 0) { continue; } diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index e993b512e5..84e1467a15 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -64,6 +64,9 @@ typedef struct FFGPUResult { uint64_t deviceId; } FFGPUResult; +static_assert(sizeof(((FFGPUResult*) NULL)->pcieSpeed) == 8, "pcieSpeed is not 8 bytes"); +static_assert(sizeof(((FFGPUResult*) NULL)->psMax) == 4, "psMax has padding"); + const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result); const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus); diff --git a/src/detection/gpu/gpu_intel.c b/src/detection/gpu/gpu_intel.c index 474f798398..04025b36c8 100644 --- a/src/detection/gpu/gpu_intel.c +++ b/src/detection/gpu/gpu_intel.c @@ -66,7 +66,10 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe } uint32_t deviceCount = 0; - if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, NULL)) { + // ctlEnumerateDevices MUST be called with deviceCount = 0 and devices = NULL first, + // otherwise it will be silently ignored and return CTL_RESULT_SUCCESS with deviceCount and devices unmodified. + // VERY STRANGE BEHAVIOR + if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, NULL) != CTL_RESULT_SUCCESS) { return "ctlEnumerateDevices(NULL) failed"; } if (deviceCount == 0) { @@ -74,7 +77,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe } FF_AUTO_FREE ctl_device_adapter_handle_t* devices = malloc(deviceCount * sizeof(*devices)); - if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, devices)) { + if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, devices) != CTL_RESULT_SUCCESS) { return "ctlEnumerateDevices(devices) failed"; } diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 8cadb9e31e..7183b903bf 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -410,34 +410,6 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf pciDetectDriver(&gpu->driver, deviceDir, buffer, drmKey); ffStrbufSubstrBefore(deviceDir, drmDirPathLength); - ffStrbufAppendS(deviceDir, "/max_link_speed"); - if (ffReadFileBuffer(deviceDir->chars, buffer)) { - gpu->psMax.gen = pcieLinkSpeedToGen(buffer); - } - ffStrbufSubstrBefore(deviceDir, drmDirPathLength); - - if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_UNSET) { - ffStrbufAppendS(deviceDir, "/max_link_width"); - if (ffReadFileBuffer(deviceDir->chars, buffer)) { - gpu->psMax.lanes = pcieWidthToLanes(buffer); - } - ffStrbufSubstrBefore(deviceDir, drmDirPathLength); - } - - ffStrbufAppendS(deviceDir, "/current_link_speed"); - if (ffReadFileBuffer(deviceDir->chars, buffer)) { - gpu->psCurr.gen = pcieLinkSpeedToGen(buffer); - } - ffStrbufSubstrBefore(deviceDir, drmDirPathLength); - - if (gpu->psCurr.gen != FF_GPU_PCIE_SPEED_UNSET) { - ffStrbufAppendS(deviceDir, "/current_link_width"); - if (ffReadFileBuffer(deviceDir->chars, buffer)) { - gpu->psCurr.lanes = pcieWidthToLanes(buffer); - } - ffStrbufSubstrBefore(deviceDir, drmDirPathLength); - } - if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) { bool ok = false; if (drmKey && options->driverSpecific) { @@ -473,7 +445,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf pciDetectTempGeneral(options, gpu, deviceDir, buffer); pciDetectZxSpecific(options, gpu, deviceDir, buffer); } else { - ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId) { + ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId){ .domain = pciDomain, .bus = pciBus, .device = pciDevice, @@ -487,11 +459,41 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf ffGPUFillVendorByDeviceName(gpu); + if (options->driverSpecific && gpu->pcieSpeed == FF_GPU_PCIE_SPEED_UNSET) { + ffStrbufAppendS(deviceDir, "/max_link_speed"); + if (ffReadFileBuffer(deviceDir->chars, buffer)) { + gpu->psMax.gen = pcieLinkSpeedToGen(buffer); + } + ffStrbufSubstrBefore(deviceDir, drmDirPathLength); + + if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_UNSET) { + ffStrbufAppendS(deviceDir, "/max_link_width"); + if (ffReadFileBuffer(deviceDir->chars, buffer)) { + gpu->psMax.lanes = pcieWidthToLanes(buffer); + } + ffStrbufSubstrBefore(deviceDir, drmDirPathLength); + } + + ffStrbufAppendS(deviceDir, "/current_link_speed"); + if (ffReadFileBuffer(deviceDir->chars, buffer)) { + gpu->psCurr.gen = pcieLinkSpeedToGen(buffer); + } + ffStrbufSubstrBefore(deviceDir, drmDirPathLength); + + if (gpu->psCurr.gen != FF_GPU_PCIE_SPEED_UNSET) { + ffStrbufAppendS(deviceDir, "/current_link_width"); + if (ffReadFileBuffer(deviceDir->chars, buffer)) { + gpu->psCurr.lanes = pcieWidthToLanes(buffer); + } + ffStrbufSubstrBefore(deviceDir, drmDirPathLength); + } + } + return NULL; } #if __aarch64__ -#include "detection/cpu/cpu.h" + #include "detection/cpu/cpu.h" FF_A_UNUSED static const char* drmDetectAsahiSpecific(FFGPUResult* gpu, const char* name, FF_A_UNUSED FFstrbuf* buffer, FF_A_UNUSED const char* drmKey) { if (sscanf(name, "agx-t%lu", &gpu->deviceId) == 1) { diff --git a/src/detection/gpu/gpu_mthreads.c b/src/detection/gpu/gpu_mthreads.c index 0b639f5037..8d5271935e 100644 --- a/src/detection/gpu/gpu_mthreads.c +++ b/src/detection/gpu/gpu_mthreads.c @@ -190,6 +190,20 @@ const char* ffDetectMthreadsGpuInfo(const FFGpuDriverCondition* cond, FFGpuDrive } } + if (result.psCurr || result.psMax) { + MtmlPciInfo pciInfo; + if (mtmlData.ffmtmlDeviceGetPciInfo(device, &pciInfo) == MTML_SUCCESS) { + if (result.psCurr) { + result.psCurr->lanes = (uint16_t) pciInfo.pciCurWidth; + result.psCurr->gen = (uint16_t) pciInfo.pciCurGen; + } + if (result.psMax) { + result.psMax->lanes = (uint16_t) pciInfo.pciMaxWidth; + result.psMax->gen = (uint16_t) pciInfo.pciMaxGen; + } + } + } + return NULL; #else diff --git a/src/detection/gpu/gpu_windows.c b/src/detection/gpu/gpu_windows.c index 18f07d2d56..5787b6d6dc 100644 --- a/src/detection/gpu/gpu_windows.c +++ b/src/detection/gpu/gpu_windows.c @@ -21,7 +21,7 @@ #define GUID_DEVCLASS_DISPLAY_STRING L"{4d36e968-e325-11ce-bfc1-08002be10318}" // Found in -static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds) { +static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds, bool queryPcieGen) { FF_DEBUG("Query PCI device info: %08llX", gpu->deviceId); static FFlist deviceIdsCache; @@ -107,42 +107,44 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds FF_DEBUG("Failed to get PCI bus number"); } - DEVPROPTYPE propType; + if (queryPcieGen) { + DEVPROPTYPE propType; - pciBufLen = sizeof(entry->maxLinkSpeed); - // Reports PCEe gen despite the PKEY name - CONFIGRET ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkSpeed, &propType, (PBYTE) &entry->maxLinkSpeed, &pciBufLen, 0); - if (ret == CR_SUCCESS) { - FF_DEBUG("PCIe max GEN: %u", entry->maxLinkSpeed); - } else { - FF_DEBUG("Failed to get PCIe max GEN: %s", ffDebugConfigRet(ret)); - } - - if (entry->maxLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) { - pciBufLen = sizeof(entry->maxLinkWidth); - ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkWidth, &propType, (PBYTE) &entry->maxLinkWidth, &pciBufLen, 0); + pciBufLen = sizeof(entry->maxLinkSpeed); + // Reports PCIe gen despite the PKEY name + CONFIGRET ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkSpeed, &propType, (PBYTE) &entry->maxLinkSpeed, &pciBufLen, 0); if (ret == CR_SUCCESS) { - FF_DEBUG("PCIe max link width: %u", entry->maxLinkWidth); + FF_DEBUG("PCIe max GEN: %u", entry->maxLinkSpeed); } else { - FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret)); + FF_DEBUG("Failed to get PCIe max GEN: %s", ffDebugConfigRet(ret)); } - } - pciBufLen = sizeof(entry->currentLinkSpeed); - ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkSpeed, &propType, (PBYTE) &entry->currentLinkSpeed, &pciBufLen, 0); - if (ret == CR_SUCCESS) { - FF_DEBUG("PCIe GEN: %u", entry->currentLinkSpeed); - } else { - FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret)); - } + if (entry->maxLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) { + pciBufLen = sizeof(entry->maxLinkWidth); + ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkWidth, &propType, (PBYTE) &entry->maxLinkWidth, &pciBufLen, 0); + if (ret == CR_SUCCESS) { + FF_DEBUG("PCIe max link width: %u", entry->maxLinkWidth); + } else { + FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret)); + } + } - if (entry->currentLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) { - pciBufLen = sizeof(entry->currentLinkWidth); - ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkWidth, &propType, (PBYTE) &entry->currentLinkWidth, &pciBufLen, 0); + pciBufLen = sizeof(entry->currentLinkSpeed); + ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkSpeed, &propType, (PBYTE) &entry->currentLinkSpeed, &pciBufLen, 0); if (ret == CR_SUCCESS) { - FF_DEBUG("PCIe current link width: %u", entry->currentLinkWidth); + FF_DEBUG("PCIe GEN: %u", entry->currentLinkSpeed); } else { - FF_DEBUG("Failed to get PCIe current link width: %s", ffDebugConfigRet(ret)); + FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret)); + } + + if (entry->currentLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) { + pciBufLen = sizeof(entry->currentLinkWidth); + ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkWidth, &propType, (PBYTE) &entry->currentLinkWidth, &pciBufLen, 0); + if (ret == CR_SUCCESS) { + FF_DEBUG("PCIe current link width: %u", entry->currentLinkWidth); + } else { + FF_DEBUG("Failed to get PCIe current link width: %s", ffDebugConfigRet(ret)); + } } } } @@ -154,10 +156,13 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds if (outDeviceIds->VendorID != -1u) { *outDeviceIds = entry->deviceIds; } - gpu->psMax.gen = (uint16_t) entry->maxLinkSpeed; - gpu->psMax.lanes = (uint16_t) entry->maxLinkWidth; - gpu->psCurr.gen = (uint16_t) entry->currentLinkSpeed; - gpu->psCurr.lanes = (uint16_t) entry->currentLinkWidth; + + if (queryPcieGen) { + gpu->psMax.gen = (uint16_t) entry->maxLinkSpeed; + gpu->psMax.lanes = (uint16_t) entry->maxLinkWidth; + gpu->psCurr.gen = (uint16_t) entry->currentLinkSpeed; + gpu->psCurr.lanes = (uint16_t) entry->currentLinkWidth; + } return true; } } @@ -371,9 +376,9 @@ ffGPUDetectWsl2 FF_DEBUG("KMTQAITYPE_PHYSICALADAPTERDEVICEIDS query failed for adapter #%u: %s", i, ffDebugNtStatus(status)); } - #if _WIN32 - if (adapterAddress.BusNumber != -1u) { - if (queryPciDeviceInfo(gpu, &deviceIds.DeviceIds) && gpu->vendor.length == 0) { + #if _WIN32 && FF_WIN81_COMPAT + if (adapterAddress.BusNumber != -1u && (deviceIds.DeviceIds.VendorID == -1u || options->driverSpecific)) { + if (queryPciDeviceInfo(gpu, &deviceIds.DeviceIds, options->driverSpecific) && gpu->vendor.length == 0) { ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(deviceIds.DeviceIds.VendorID)); } } @@ -448,6 +453,12 @@ ffGPUDetectWsl2 FF_DEBUG("Attempting to query vendor name via registry for adapter #%u", i); queryVendorNameViaRegistry(&gpu->vendor, adapter->hAdapter); } + + #if !FF_WIN81_COMPAT + if (adapterAddress.BusNumber != -1u && options->driverSpecific && gpu->pcieSpeed == FF_GPU_PCIE_SPEED_UNSET) { + queryPciDeviceInfo(gpu, &deviceIds.DeviceIds, options->driverSpecific); + } + #endif #endif if (gpu->name.length == 0) { diff --git a/src/detection/memory/memory_bsd.c b/src/detection/memory/memory_bsd.c index f76f6b8b4f..6deadd6358 100644 --- a/src/detection/memory/memory_bsd.c +++ b/src/detection/memory/memory_bsd.c @@ -9,8 +9,15 @@ const char* ffDetectMemory(FFMemoryResult* ram) { // vm.stats.vm.* are int values int32_t pagesFree = ffSysctlGetInt("vm.stats.vm.v_free_count", 0) + ffSysctlGetInt("vm.stats.vm.v_inactive_count", 0) + ffSysctlGetInt("vm.stats.vm.v_cache_count", 0); + int64_t bytesCache = ffSysctlGetInt64("vfs.bufspace", 0); - ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize; + ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize - (uint64_t) bytesCache; + + int64_t bytesArc = ffSysctlGetInt64("kstat.zfs.misc.arcstats.size", 0); + if (bytesArc > 0) bytesArc -= ffSysctlGetInt64("kstat.zfs.misc.arcstats.c_min", 0); + if (bytesArc > 0 && (uint64_t) bytesArc < ram->bytesUsed) { + ram->bytesUsed -= (uint64_t) bytesArc; + } return NULL; } diff --git a/src/detection/memory/memory_linux.c b/src/detection/memory/memory_linux.c index 74d20a0315..cd2c8989e1 100644 --- a/src/detection/memory/memory_linux.c +++ b/src/detection/memory/memory_linux.c @@ -1,8 +1,5 @@ #include "memory.h" #include "common/io.h" -#include "common/mallocHelper.h" - -#include const char* ffDetectMemory(FFMemoryResult* ram) { char buf[PROC_FILE_BUFFSIZ]; @@ -21,35 +18,35 @@ const char* ffDetectMemory(FFMemoryResult* ram) { sReclaimable = 0; char* token = NULL; - if ((token = strstr(buf, "MemTotal:")) != NULL) { - memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10); + if ((token = memmem(buf, (size_t) nRead, "MemTotal:", strlen("MemTotal:"))) != NULL) { + memTotal = (uint64_t) strtoull(token + strlen("MemTotal:"), NULL, 10); } else { return "MemTotal not found in /proc/meminfo"; } - if ((token = strstr(buf, "MemAvailable:")) != NULL) { - memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10); + if ((token = memmem(buf, (size_t) nRead, "MemAvailable:", strlen("MemAvailable:"))) != NULL) { + memAvailable = (uint64_t) strtoull(token + strlen("MemAvailable:"), NULL, 10); } - if (memAvailable == 0 || memAvailable >= memTotal) // MemAvailable can be unreasonable. #1988 - { - if ((token = strstr(buf, "MemFree:")) != NULL) { - memFree = strtoul(token + strlen("MemFree:"), NULL, 10); + + if (memAvailable == 0 || memAvailable >= memTotal) { // MemAvailable can be unreasonable. #1988 + if ((token = memmem(buf, (size_t) nRead, "MemFree:", strlen("MemFree:"))) != NULL) { + memFree = (uint64_t) strtoull(token + strlen("MemFree:"), NULL, 10); } - if ((token = strstr(buf, "Buffers:")) != NULL) { - buffers = strtoul(token + strlen("Buffers:"), NULL, 10); + if ((token = memmem(buf, (size_t) nRead, "Buffers:", strlen("Buffers:"))) != NULL) { + buffers = (uint64_t) strtoull(token + strlen("Buffers:"), NULL, 10); } - if ((token = strstr(buf, "Cached:")) != NULL) { - cached = strtoul(token + strlen("Cached:"), NULL, 10); + if ((token = memmem(buf, (size_t) nRead, "Cached:", strlen("Cached:"))) != NULL) { + cached = (uint64_t) strtoull(token + strlen("Cached:"), NULL, 10); } - if ((token = strstr(buf, "Shmem:")) != NULL) { - shmem = strtoul(token + strlen("Shmem:"), NULL, 10); + if ((token = memmem(buf, (size_t) nRead, "Shmem:", strlen("Shmem:"))) != NULL) { + shmem = (uint64_t) strtoull(token + strlen("Shmem:"), NULL, 10); } - if ((token = strstr(buf, "SReclaimable:")) != NULL) { - sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10); + if ((token = memmem(buf, (size_t) nRead, "SReclaimable:", strlen("SReclaimable:"))) != NULL) { + sReclaimable = (uint64_t) strtoull(token + strlen("SReclaimable:"), NULL, 10); } memAvailable = memFree + buffers + cached + sReclaimable - shmem; @@ -58,5 +55,47 @@ const char* ffDetectMemory(FFMemoryResult* ram) { ram->bytesTotal = memTotal * 1024lu; ram->bytesUsed = (memTotal - memAvailable) * 1024lu; + uint64_t arcSize = 0; + nRead = ffReadFileData("/proc/spl/kstat/zfs/arcstats", ARRAY_SIZE(buf) - 1, buf); + if (nRead > 0) { + buf[nRead] = '\0'; + // 24 1 0x01 148 40256 2053603602 851614020716 + // name type data + // hits 4 752 + + // Skip first line + const char* p = memchr(buf, '\n', (size_t) nRead); + if (__builtin_expect(p != NULL, true)) { + ++p; + nRead -= (p - buf); + assert(nRead > 0); + + // Find line offset of data + const char* pData = memmem(p, (size_t) nRead, "data\n", strlen("data\n")); + if (__builtin_expect(pData != NULL, true)) { + uint32_t dataOffset = (uint32_t) (pData - p); + p += dataOffset + strlen("data\n"); + nRead -= (ssize_t) (dataOffset + strlen("data\n")); + assert(nRead > 0); + + if ((token = memmem(p, (size_t) nRead, "\nsize ", strlen("\nsize "))) != NULL) { + arcSize = (uint64_t) strtoull(token + 1 + dataOffset, NULL, 10); + if (arcSize > 0) { + uint64_t arcMin = 0; + if ((token = memmem(p, (size_t) nRead, "\nc_min ", strlen("\nc_min "))) != NULL) { + arcMin = (uint64_t) strtoull(token + 1 + dataOffset, NULL, 10); + if (arcSize > arcMin) { + arcSize -= arcMin; + if (ram->bytesUsed > arcSize) { + ram->bytesUsed -= arcSize; + } + } + } + } + } + } + } + } + return NULL; } diff --git a/src/detection/memory/memory_nbsd.c b/src/detection/memory/memory_nbsd.c index ca094755e7..f7330ea316 100644 --- a/src/detection/memory/memory_nbsd.c +++ b/src/detection/memory/memory_nbsd.c @@ -14,5 +14,11 @@ const char* ffDetectMemory(FFMemoryResult* ram) { ram->bytesTotal = (uint64_t) buf.npages * instance.state.platform.sysinfo.pageSize; ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) * instance.state.platform.sysinfo.pageSize; + int64_t bytesArc = ffSysctlGetInt64("kstat.zfs.misc.arcstats.size", 0); + if (bytesArc > 0) bytesArc -= ffSysctlGetInt64("kstat.zfs.misc.arcstats.c_min", 0); + if (bytesArc > 0 && (uint64_t) bytesArc < ram->bytesUsed) { + ram->bytesUsed -= (uint64_t) bytesArc; + } + return NULL; } diff --git a/src/detection/memory/memory_sunos.c b/src/detection/memory/memory_sunos.c index 7dfdeab959..844ce9e241 100644 --- a/src/detection/memory/memory_sunos.c +++ b/src/detection/memory/memory_sunos.c @@ -1,9 +1,43 @@ #include "memory.h" #include +#include + +static inline void kstatFreeWrap(kstat_ctl_t** pkc) { + assert(pkc); + if (*pkc) { + kstat_close(*pkc); + } +} const char* ffDetectMemory(FFMemoryResult* ram) { - ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) * instance.state.platform.sysinfo.pageSize; - ram->bytesUsed = ram->bytesTotal - (uint64_t) sysconf(_SC_AVPHYS_PAGES) * instance.state.platform.sysinfo.pageSize; + uint64_t pageSize = instance.state.platform.sysinfo.pageSize; + + ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) * pageSize; + ram->bytesUsed = ram->bytesTotal - (uint64_t) sysconf(_SC_AVPHYS_PAGES) * pageSize; + + FF_A_CLEANUP(kstatFreeWrap) kstat_ctl_t* kc = kstat_open(); + if (kc != NULL) { + kstat_t* ksp = kstat_lookup(kc, "zfs", -1, "arcstats"); + if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1) { + kstat_named_t* kn_size = (kstat_named_t*) kstat_data_lookup(ksp, "size"); + kstat_named_t* kn_cmin = (kstat_named_t*) kstat_data_lookup(ksp, "c_min"); + + if (kn_size != NULL && kn_cmin != NULL && + kn_size->data_type == KSTAT_DATA_UINT64 && + kn_cmin->data_type == KSTAT_DATA_UINT64) { + uint64_t arcSize = kn_size->value.ui64; + uint64_t arcMin = kn_cmin->value.ui64; + + if (arcSize > arcMin) { + uint64_t reclaimableArc = arcSize - arcMin; + + if (ram->bytesUsed > reclaimableArc) { + ram->bytesUsed -= reclaimableArc; + } + } + } + } + } return NULL; } diff --git a/src/logo/ascii/c.inc b/src/logo/ascii/c.inc index 2cf1a4a2aa..62be28e3de 100644 --- a/src/logo/ascii/c.inc +++ b/src/logo/ascii/c.inc @@ -9,12 +9,12 @@ static const FFlogo C[] = { .names = { "CachyOS" }, .lines = FASTFETCH_DATATEXT_LOGO_CACHYOS, .colors = { - FF_COLOR_FG_CYAN, FF_COLOR_FG_GREEN, + FF_COLOR_FG_CYAN, FF_COLOR_FG_BLACK, }, .colorKeys = FF_COLOR_FG_CYAN, - .colorTitle = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_GREEN, }, #endif #ifdef FASTFETCH_DATATEXT_LOGO_CACHYOS_SMALL @@ -24,10 +24,24 @@ static const FFlogo C[] = { .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_CACHYOS_SMALL, .colors = { + FF_COLOR_FG_GREEN, FF_COLOR_FG_CYAN, }, .colorKeys = FF_COLOR_FG_CYAN, - .colorTitle = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + #endif + #ifdef FASTFETCH_DATATEXT_LOGO_CACHYOS_OLD_SMALL + // CachyOSOldSmall + { + .names = { "CachyOS_old_small" }, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_CACHYOS_OLD_SMALL, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_GREEN, }, #endif #ifdef FASTFETCH_DATATEXT_LOGO_CALCULATE diff --git a/src/logo/ascii/c/cachyos_old_small.txt b/src/logo/ascii/c/cachyos_old_small.txt new file mode 100644 index 0000000000..6497db48cb --- /dev/null +++ b/src/logo/ascii/c/cachyos_old_small.txt @@ -0,0 +1,8 @@ + /''''''''''''/ + /''''''''''''/ + /''''''/ +/''''''/ +\......\ + \......\ + \.............../ + \............./ \ No newline at end of file diff --git a/src/logo/ascii/c/cachyos_small.txt b/src/logo/ascii/c/cachyos_small.txt index 6497db48cb..73d5dc454d 100644 --- a/src/logo/ascii/c/cachyos_small.txt +++ b/src/logo/ascii/c/cachyos_small.txt @@ -1,8 +1,11 @@ - /''''''''''''/ - /''''''''''''/ - /''''''/ -/''''''/ -\......\ - \......\ - \.............../ - \............./ \ No newline at end of file + ........... + $2/,,,,$1...../ + $2/,,,$1..$2,,$1../ $2() + $2/,,,,$1../ + $2/,,,$1.../ $1/'\ +$2/,$1...../ $2\,/ +$2\,,,,,,\\ $1_ + $2\,,$1....\\ $1/ \ + $1\...$2,$1..\\ $2\_/ + $1\..$2,,,,,,,,,,,,/ + $1\$2,,$1........$2,,/ \ No newline at end of file diff --git a/src/logo/ascii/t.inc b/src/logo/ascii/t.inc index 53947eab5a..3adf4784a3 100644 --- a/src/logo/ascii/t.inc +++ b/src/logo/ascii/t.inc @@ -122,6 +122,18 @@ static const FFlogo T[] = { .colorTitle = FF_COLOR_FG_256 "32", }, #endif + #ifdef FASTFETCH_DATATEXT_LOGO_TURKISH + // Turkish + { + .names = { "Turkish", }, + .lines = FASTFETCH_DATATEXT_LOGO_TURKISH, + .colors = { + FF_COLOR_FG_DEFAULT, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_RED, + }, + #endif #ifdef FASTFETCH_DATATEXT_LOGO_TUXEDO_OS // TuxedoOS { diff --git a/src/logo/ascii/t/turkish.txt b/src/logo/ascii/t/turkish.txt new file mode 100644 index 0000000000..10a53786ca --- /dev/null +++ b/src/logo/ascii/t/turkish.txt @@ -0,0 +1,20 @@ + @@@@@@@@@ + @@@@@@ @@ + @@@@@ + @@@@@ +@@@@@@ + @@@@@ @@@@@ + @@@@@@ @@@@@@@@@@@@@ + @@@@@@@ @@ @@@@@@ @ + @@@@@@@@@@@ @@@@@ + @@@@ + @@@@ + @@@@@@@@@@ @@@@@ + @@@@@@@ @@ @@@@@@ @ + @@@@@@ @@@@@@@@@@@@@ + @@@@@ @@@@@@@ +@@@@@@ + @@@@@ + @@@@@ + @@@@@@ @@ + @@@@@@@@@@ \ No newline at end of file