From a6822e98434cf7da6fab033898094976d881ee0f Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Fri, 4 Feb 2022 11:23:02 +0100 Subject: New upstream version 3.1.2 --- linux/Platform.c | 254 +++++++++++++++++++++---------------------------------- 1 file changed, 95 insertions(+), 159 deletions(-) (limited to 'linux/Platform.c') diff --git a/linux/Platform.c b/linux/Platform.c index e305e7f..93953e8 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -611,133 +611,85 @@ bool Platform_getNetworkIO(NetworkIOData* data) { // Linux battery reading by Ian P. Hands (iphands@gmail.com, ihands@redhat.com). -#define MAX_BATTERIES 64 #define PROC_BATTERY_DIR PROCDIR "/acpi/battery" #define PROC_POWERSUPPLY_DIR PROCDIR "/acpi/ac_adapter" +#define PROC_POWERSUPPLY_ACSTATE_FILE PROC_POWERSUPPLY_DIR "/AC/state" #define SYS_POWERSUPPLY_DIR "/sys/class/power_supply" // ---------------------------------------- // READ FROM /proc // ---------------------------------------- -static unsigned long int parseBatInfo(const char* fileName, const unsigned short int lineNum, const unsigned short int wordNum) { - const char batteryPath[] = PROC_BATTERY_DIR; - DIR* batteryDir = opendir(batteryPath); +static double Platform_Battery_getProcBatInfo(void) { + DIR* batteryDir = opendir(PROC_BATTERY_DIR); if (!batteryDir) - return 0; - - char* batteries[MAX_BATTERIES]; - unsigned int nBatteries = 0; - memset(batteries, 0, MAX_BATTERIES * sizeof(char*)); + return NAN; - while (nBatteries < MAX_BATTERIES) { - const struct dirent* dirEntry = readdir(batteryDir); - if (!dirEntry) - break; + uint64_t totalFull = 0; + uint64_t totalRemain = 0; + struct dirent* dirEntry = NULL; + while ((dirEntry = readdir(batteryDir))) { const char* entryName = dirEntry->d_name; if (!String_startsWith(entryName, "BAT")) continue; - batteries[nBatteries] = xStrdup(entryName); - nBatteries++; - } - closedir(batteryDir); + char filePath[256]; + char bufInfo[1024] = {0}; + xSnprintf(filePath, sizeof(filePath), "%s/%s/info", PROC_BATTERY_DIR, entryName); + ssize_t r = xReadfile(filePath, bufInfo, sizeof(bufInfo)); + if (r < 0) + continue; - unsigned long int total = 0; - for (unsigned int i = 0; i < nBatteries; i++) { - char infoPath[30]; - xSnprintf(infoPath, sizeof infoPath, "%s%s/%s", batteryPath, batteries[i], fileName); + char bufState[1024] = {0}; + xSnprintf(filePath, sizeof(filePath), "%s/%s/state", PROC_BATTERY_DIR, entryName); + r = xReadfile(filePath, bufState, sizeof(bufState)); + if (r < 0) + continue; - FILE* file = fopen(infoPath, "r"); - if (!file) - break; + const char* line; + + //Getting total charge for all batteries + char* buf = bufInfo; + while ((line = strsep(&buf, "\n")) != NULL) { + char field[100] = {0}; + int val = 0; + if (2 != sscanf(line, "%99[^:]:%d", field, &val)) + continue; - char* line = NULL; - for (unsigned short int j = 0; j < lineNum; j++) { - free(line); - line = String_readLine(file); - if (!line) + if (String_eq(field, "last full capacity")) { + totalFull += val; break; + } } - fclose(file); - - if (!line) - break; - - char* foundNumStr = String_getToken(line, wordNum); - const unsigned long int foundNum = atoi(foundNumStr); - free(foundNumStr); - free(line); + //Getting remaining charge for all batteries + buf = bufState; + while ((line = strsep(&buf, "\n")) != NULL) { + char field[100] = {0}; + int val = 0; + if (2 != sscanf(line, "%99[^:]:%d", field, &val)) + continue; - total += foundNum; + if (String_eq(field, "remaining capacity")) { + totalRemain += val; + break; + } + } } - for (unsigned int i = 0; i < nBatteries; i++) - free(batteries[i]); + closedir(batteryDir); - return total; + return totalFull > 0 ? ((double) totalRemain * 100.0) / (double) totalFull : NAN; } static ACPresence procAcpiCheck(void) { - ACPresence isOn = AC_ERROR; - const char* power_supplyPath = PROC_POWERSUPPLY_DIR; - DIR* dir = opendir(power_supplyPath); - if (!dir) + char buffer[1024] = {0}; + ssize_t r = xReadfile(PROC_POWERSUPPLY_ACSTATE_FILE, buffer, sizeof(buffer)); + if (r < 1) return AC_ERROR; - for (;;) { - const struct dirent* dirEntry = readdir(dir); - if (!dirEntry) - break; - - const char* entryName = dirEntry->d_name; - - if (entryName[0] != 'A') - continue; - - char statePath[256]; - xSnprintf(statePath, sizeof(statePath), "%s/%s/state", power_supplyPath, entryName); - FILE* file = fopen(statePath, "r"); - if (!file) { - isOn = AC_ERROR; - continue; - } - char* line = String_readLine(file); - - fclose(file); - - if (!line) - continue; - - char* isOnline = String_getToken(line, 2); - free(line); - - if (String_eq(isOnline, "on-line")) - isOn = AC_PRESENT; - else - isOn = AC_ABSENT; - free(isOnline); - if (isOn == AC_PRESENT) - break; - } - - closedir(dir); - - return isOn; -} - -static double Platform_Battery_getProcBatInfo(void) { - const unsigned long int totalFull = parseBatInfo("info", 3, 4); - if (totalFull == 0) - return NAN; - - const unsigned long int totalRemain = parseBatInfo("state", 5, 3); - if (totalRemain == 0) - return NAN; - - return totalRemain * 100.0 / (double) totalFull; + return String_eq(buffer, "on-line") ? AC_PRESENT : AC_ABSENT; } static void Platform_Battery_getProcData(double* percent, ACPresence* isOnAC) { @@ -750,7 +702,6 @@ static void Platform_Battery_getProcData(double* percent, ACPresence* isOnAC) { // ---------------------------------------- static void Platform_Battery_getSysData(double* percent, ACPresence* isOnAC) { - *percent = NAN; *isOnAC = AC_ERROR; @@ -758,68 +709,52 @@ static void Platform_Battery_getSysData(double* percent, ACPresence* isOnAC) { if (!dir) return; - unsigned long int totalFull = 0; - unsigned long int totalRemain = 0; - - for (;;) { - const struct dirent* dirEntry = readdir(dir); - if (!dirEntry) - break; + uint64_t totalFull = 0; + uint64_t totalRemain = 0; + struct dirent* dirEntry = NULL; + while ((dirEntry = readdir(dir))) { const char* entryName = dirEntry->d_name; - char filePath[256]; - - xSnprintf(filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/type", entryName); - char type[8]; - ssize_t r = xReadfile(filePath, type, sizeof(type)); - if (r < 3) - continue; - - if (type[0] == 'B' && type[1] == 'a' && type[2] == 't') { + if (String_startsWith(entryName, "BAT")) { + char buffer[1024] = {0}; + char filePath[256]; xSnprintf(filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/uevent", entryName); - char buffer[1024]; - r = xReadfile(filePath, buffer, sizeof(buffer)); - if (r < 0) { - closedir(dir); - return; - } + ssize_t r = xReadfile(filePath, buffer, sizeof(buffer)); + if (r < 0) + continue; - char* buf = buffer; - const char* line; bool full = false; bool now = false; - int fullSize = 0; - double capacityLevel = NAN; - #define match(str,prefix) \ - (String_startsWith(str,prefix) ? (str) + strlen(prefix) : NULL) + double fullCharge = 0; + double capacityLevel = NAN; + const char* line; + char* buf = buffer; while ((line = strsep(&buf, "\n")) != NULL) { - const char* ps = match(line, "POWER_SUPPLY_"); - if (!ps) + char field[100] = {0}; + int val = 0; + if (2 != sscanf(line, "POWER_SUPPLY_%99[^=]=%d", field, &val)) continue; - const char* capacity = match(ps, "CAPACITY="); - if (capacity) - capacityLevel = atoi(capacity) / 100.0; - const char* energy = match(ps, "ENERGY_"); - if (!energy) - energy = match(ps, "CHARGE_"); - if (!energy) + + if (String_eq(field, "CAPACITY")) { + capacityLevel = val / 100.0; continue; - const char* value = (!full) ? match(energy, "FULL=") : NULL; - if (value) { - fullSize = atoi(value); - totalFull += fullSize; + } + + if (String_eq(field, "ENERGY_FULL") || String_eq(field, "CHARGE_FULL")) { + fullCharge = val; + totalFull += fullCharge; full = true; if (now) break; continue; } - value = (!now) ? match(energy, "NOW=") : NULL; - if (value) { - totalRemain += atoi(value); + + if (String_eq(field, "ENERGY_NOW") || String_eq(field, "CHARGE_NOW")) { + totalRemain += val; now = true; if (full) break; @@ -827,23 +762,21 @@ static void Platform_Battery_getSysData(double* percent, ACPresence* isOnAC) { } } - #undef match - if (!now && full && !isnan(capacityLevel)) - totalRemain += (capacityLevel * fullSize); + totalRemain += capacityLevel * fullCharge; - } else if (entryName[0] == 'A') { + } else if (String_startsWith(entryName, "AC")) { + char buffer[2] = {0}; if (*isOnAC != AC_ERROR) continue; - xSnprintf(filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/online", entryName); - - char buffer[2]; + char filePath[256]; + xSnprintf(filePath, sizeof(filePath), SYS_POWERSUPPLY_DIR "/%s/online", entryName); - r = xReadfile(filePath, buffer, sizeof(buffer)); + ssize_t r = xReadfile(filePath, buffer, sizeof(buffer)); if (r < 1) { - closedir(dir); - return; + *isOnAC = AC_ERROR; + continue; } if (buffer[0] == '0') @@ -852,6 +785,7 @@ static void Platform_Battery_getSysData(double* percent, ACPresence* isOnAC) { *isOnAC = AC_PRESENT; } } + closedir(dir); *percent = totalFull > 0 ? ((double) totalRemain * 100.0) / (double) totalFull : NAN; @@ -901,7 +835,7 @@ void Platform_longOptionsUsage(const char* name) #endif } -bool Platform_getLongOption(int opt, int argc, char** argv) { +CommandLineStatus Platform_getLongOption(int opt, int argc, char** argv) { #ifndef HAVE_LIBCAP (void) argc; (void) argv; @@ -924,16 +858,16 @@ bool Platform_getLongOption(int opt, int argc, char** argv) { Platform_capabilitiesMode = CAP_MODE_STRICT; } else { fprintf(stderr, "Error: invalid capabilities mode \"%s\".\n", mode); - exit(1); + return STATUS_ERROR_EXIT; } - return true; + return STATUS_OK; } #endif default: break; } - return false; + return STATUS_ERROR_EXIT; } #ifdef HAVE_LIBCAP @@ -1022,20 +956,22 @@ static int dropCapabilities(enum CapMode mode) { } #endif -void Platform_init(void) { +bool Platform_init(void) { #ifdef HAVE_LIBCAP if (dropCapabilities(Platform_capabilitiesMode) < 0) - exit(1); + return false; #endif if (access(PROCDIR, R_OK) != 0) { fprintf(stderr, "Error: could not read procfs (compiled to look in %s).\n", PROCDIR); - exit(1); + return false; } #ifdef HAVE_SENSORS_SENSORS_H LibSensors_init(); #endif + + return true; } void Platform_done(void) { -- cgit v1.2.3