From ae76d2d032de474280c4d336c31d0f8ae4347828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Oct 2024 19:40:03 +0800 Subject: [PATCH] IO (Linux): improve performance of `ffPathExists` --- src/common/io/io.h | 26 ++++++++++++++++---------- src/detection/bios/bios_bsd.c | 2 +- src/detection/bios/bios_linux.c | 2 +- src/detection/tpm/tpm_linux.c | 4 ++-- src/detection/wifi/wifi_linux.c | 2 +- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/common/io/io.h b/src/common/io/io.h index 908169985..06ab29106 100644 --- a/src/common/io/io.h +++ b/src/common/io/io.h @@ -13,6 +13,7 @@ #include #include #include + #include typedef int FFNativeFD; #define FF_INVALID_FD (-1) // procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime. @@ -116,17 +117,22 @@ static inline bool ffPathExists(const char* path, FFPathType pathType) } else { - struct stat fileStat; - if(stat(path, &fileStat) != 0) - return false; + size_t len = strlen(path); + assert(len < PATH_MAX); + if (len == 0) return false; - unsigned int mode = fileStat.st_mode & S_IFMT; - - if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR) - return true; - - if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR) - return true; + int ret; + if (path[len - 1] != '/') + { + char buf[PATH_MAX + 1]; + memcpy(buf, path, len); + buf[len] = '/'; + buf[len + 1] = 0; + ret = access(buf, F_OK); + } + else + ret = access(path, F_OK); + return pathType == FF_PATHTYPE_DIRECTORY ? ret == 0 : ret == -1 && errno == ENOTDIR; } #endif diff --git a/src/detection/bios/bios_bsd.c b/src/detection/bios/bios_bsd.c index aa115de21..11f762099 100644 --- a/src/detection/bios/bios_bsd.c +++ b/src/detection/bios/bios_bsd.c @@ -25,7 +25,7 @@ const char* ffDetectBios(FFBiosResult* result) { ffStrbufSetStatic(&result->type, ffPathExists("/dev/efi" /*efidev*/, FF_PATHTYPE_FILE) || - ffPathExists("/boot/efi/efi" /*efi partition*/, FF_PATHTYPE_DIRECTORY) + ffPathExists("/boot/efi/efi/" /*efi partition*/, FF_PATHTYPE_DIRECTORY) ? "UEFI" : "BIOS"); } } diff --git a/src/detection/bios/bios_linux.c b/src/detection/bios/bios_linux.c index 86342c159..98bb40c38 100644 --- a/src/detection/bios/bios_linux.c +++ b/src/detection/bios/bios_linux.c @@ -10,7 +10,7 @@ const char *ffDetectBios(FFBiosResult *bios) ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release); ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->vendor); ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->version); - if (ffPathExists("/sys/firmware/efi", FF_PATHTYPE_DIRECTORY) || ffPathExists("/sys/firmware/acpi/tables/UEFI", FF_PATHTYPE_FILE)) + if (ffPathExists("/sys/firmware/efi/", FF_PATHTYPE_DIRECTORY) || ffPathExists("/sys/firmware/acpi/tables/UEFI", FF_PATHTYPE_FILE)) ffStrbufSetStatic(&bios->type, "UEFI"); else ffStrbufSetStatic(&bios->type, "BIOS"); diff --git a/src/detection/tpm/tpm_linux.c b/src/detection/tpm/tpm_linux.c index 2547339c6..90c7cf7c1 100644 --- a/src/detection/tpm/tpm_linux.c +++ b/src/detection/tpm/tpm_linux.c @@ -3,9 +3,9 @@ const char* ffDetectTPM(FFTPMResult* result) { - if (!ffPathExists("/sys/class/tpm/tpm0", FF_PATHTYPE_DIRECTORY)) + if (!ffPathExists("/sys/class/tpm/tpm0/", FF_PATHTYPE_DIRECTORY)) { - if (!ffPathExists("/sys/class/tpm", FF_PATHTYPE_DIRECTORY)) + if (!ffPathExists("/sys/class/tpm/", FF_PATHTYPE_DIRECTORY)) return "TPM is not supported by kernel"; return "TPM device is not found"; } diff --git a/src/detection/wifi/wifi_linux.c b/src/detection/wifi/wifi_linux.c index b2e6e464f..2e6b90f20 100644 --- a/src/detection/wifi/wifi_linux.c +++ b/src/detection/wifi/wifi_linux.c @@ -274,7 +274,7 @@ const char* ffDetectWifi(FF_MAYBE_UNUSED FFlist* result) for(struct if_nameindex* i = infs; !(i->if_index == 0 && i->if_name == NULL); ++i) { - ffStrbufSetF(&buffer, "/sys/class/net/%s/phy80211", i->if_name); + ffStrbufSetF(&buffer, "/sys/class/net/%s/phy80211/", i->if_name); if(!ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY)) continue;