netstar pushed a commit to branch master.

http://git.enlightenment.org/apps/evisum.git/commit/?id=f9dd314951ae6fe9172f5ac40d7366f493e9ea79

commit f9dd314951ae6fe9172f5ac40d7366f493e9ea79
Author: Alastair Poole <nets...@gmail.com>
Date:   Thu Aug 29 23:55:43 2019 +0100

    Fix issues with Linux batteries and leak
---
 src/system.c        | 65 +++++++++++++++++++++++++++++++++++++++--------------
 src/system.h        |  4 ++--
 src/tingle/tingle.c | 57 ++++++++++++++++++++++++++++++++--------------
 3 files changed, 90 insertions(+), 36 deletions(-)

diff --git a/src/system.c b/src/system.c
index c8f40db..5b0612a 100644
--- a/src/system.c
+++ b/src/system.c
@@ -35,6 +35,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <math.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/sysctl.h>
@@ -337,7 +338,7 @@ _cpu_state_get(cpu_core_t **cores, int ncpu)
    count = HOST_CPU_LOAD_INFO_COUNT;
    mach_port = mach_host_self();
    if (host_processor_info(mach_port, PROCESSOR_CPU_LOAD_INFO, &cpu_count, 
(processor_info_array_t *)&load, &count) != KERN_SUCCESS)
-     exit(4 << 1);
+     exit(-1);
 
    for (i = 0; i < ncpu; i++) {
         core = cores[i];
@@ -785,6 +786,8 @@ _power_battery_count_get(power_t *power)
      }
 #elif defined(__linux__)
    struct dirent *dh;
+   struct stat st;
+   char path[PATH_MAX];
    DIR *dir;
 
    dir = opendir("/sys/class/power_supply");
@@ -793,9 +796,14 @@ _power_battery_count_get(power_t *power)
    while ((dh = readdir(dir)) != NULL)
      {
         if (dh->d_name[0] == '.') continue;
-        if (!strncmp(dh->d_name, "BAT", 3))
+
+        snprintf(path, sizeof(path), "/sys/class/power_supply/%s/type", 
dh->d_name);
+        char *type = Fcontents(path);
+        if (type)
           {
-             power->battery_names[power->battery_count++] = 
(char)dh->d_name[3];
+             if (!strncmp(type, "Battery", 7))
+               power->battery_names[power->battery_count++] = 
strdup(dh->d_name);
+             free(type);
           }
      }
 
@@ -851,48 +859,65 @@ _battery_state_get(power_t *power, int *mib)
 #elif defined(__linux__)
    char path[PATH_MAX];
    struct dirent *dh;
+   struct stat st;
    DIR *dir;
    char *buf, *naming = NULL;
    int i = 0;
    unsigned long charge_full = 0;
    unsigned long charge_current = 0;
 
-   while (power->battery_names[i] != '\0')
+   while (i < power->battery_count)
      {
-        snprintf(path, sizeof(path), "/sys/class/power_supply/BAT%c", 
power->battery_names[i]);
+        naming = NULL;
+        snprintf(path, sizeof(path), "/sys/class/power_supply/%s", 
power->battery_names[i]);
+        stat(path, &st);
+
+        if (S_ISLNK(st.st_mode)) continue;
+        if (!S_ISDIR(st.st_mode)) continue;
+
         dir = opendir(path);
         if (!dir) return;
         while ((dh = readdir(dir)) != NULL)
           {
-             if (!strcmp(dh->d_name, "energy_full"))
-               {
-                  naming = "energy"; break;
-               }
-             else if (!strcmp(dh->d_name, "capacity_full"))
-               {
-                  naming = "capacity"; break;
-               }
+             char *e;
+             if (dh->d_name[0] == '.') continue;
+
+             if ((e = strstr(dh->d_name, "_full\0")))
+              {
+                 naming = strndup(dh->d_name, e - dh->d_name);
+                 break;
+              }
           }
         closedir(dir);
+
         if (!naming) continue;
-        snprintf(path, sizeof(path), "/sys/class/power_supply/BAT%c/%s_full", 
power->battery_names[i], naming);
+
+        snprintf(path, sizeof(path), "/sys/class/power_supply/%s/%s_full", 
power->battery_names[i], naming);
         buf = Fcontents(path);
         if (buf)
           {
              charge_full = atol(buf);
              free(buf);
           }
-        snprintf(path, sizeof(path), "/sys/class/power_supply/BAT%c/%s_now", 
power->battery_names[i], naming);
+        snprintf(path, sizeof(path), "/sys/class/power_supply/%s/%s_now", 
power->battery_names[i], naming);
         buf = Fcontents(path);
         if (buf)
           {
              charge_current = atol(buf);
              free(buf);
           }
+
         power->charge_full += charge_full;
         power->charge_current += charge_current;
-        naming = NULL;
+
+        free(naming);
         i++;
+
+        if (i == MAX_BATTERIES)
+          {
+             fprintf(stderr, "Error: Should not be here!\n");
+             exit(-1);
+          }
      }
 #endif
 }
@@ -954,8 +979,14 @@ _power_state_get(power_t *power)
    power->percent = value;
 
 #endif
+
    for (i = 0; i < power->battery_count; i++)
-     if (power->bat_mibs[i]) free(power->bat_mibs[i]);
+     {
+        if (power->battery_names[i])
+          free(power->battery_names[i]);
+        if (power->bat_mibs[i])
+          free(power->bat_mibs[i]);
+     }
 }
 
 #if defined(__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__)
diff --git a/src/system.h b/src/system.h
index b37d291..f091707 100644
--- a/src/system.h
+++ b/src/system.h
@@ -30,8 +30,8 @@ typedef struct
    double  charge_full;
    double  charge_current;
    uint8_t percent;
-#define MAX_BATTERIES 5
-   char    battery_names[256];
+#define MAX_BATTERIES 10
+   char    *battery_names[MAX_BATTERIES];
    int    *bat_mibs[MAX_BATTERIES];
    int     ac_mibs[5];
 } power_t;
diff --git a/src/tingle/tingle.c b/src/tingle/tingle.c
index ced4b90..ba0c312 100644
--- a/src/tingle/tingle.c
+++ b/src/tingle/tingle.c
@@ -36,6 +36,7 @@
 #include <fcntl.h>
 #include <math.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #include <sys/ioctl.h>
@@ -84,7 +85,7 @@
 #define CPU_STATES        5
 #endif
 
-#define MAX_BATTERIES     5
+#define MAX_BATTERIES     10
 #define INVALID_TEMP      -999
 
 /* Filter requests and results */
@@ -131,7 +132,7 @@ typedef struct
 
    bat_t **batteries;
 
-   char    battery_names[256];
+   char   *battery_names[MAX_BATTERIES];
    int    *bat_mibs[MAX_BATTERIES];
    int     ac_mibs[5];
 } power_t;
@@ -995,6 +996,7 @@ _power_battery_count_get(power_t *power)
 #elif defined(__linux__)
    struct dirent *dh;
    DIR *dir;
+   char path[PATH_MAX];
 
    dir = opendir("/sys/class/power_supply");
    if (!dir) return 0;
@@ -1002,9 +1004,15 @@ _power_battery_count_get(power_t *power)
    while ((dh = readdir(dir)) != NULL)
      {
         if (dh->d_name[0] == '.') continue;
-        if (!strncmp(dh->d_name, "BAT", 3))
+
+        snprintf(path, sizeof(path), "/sys/class/power_supply/%s/type", 
dh->d_name);
+
+        char *type = Fcontents(path);
+        if (type)
           {
-             power->battery_names[power->battery_count++] = 
(char)dh->d_name[3];
+             if (!strncmp(type, "Battery", 7))
+               power->battery_names[power->battery_count++] = 
strdup(dh->d_name);
+             free(type);
           }
      }
 
@@ -1070,38 +1078,45 @@ _battery_state_get(power_t *power, int *mib)
 #elif defined(__linux__)
    char path[PATH_MAX];
    struct dirent *dh;
+   struct stat st;
    DIR *dir;
-   char *buf, *naming = NULL;
+   char *buf, *naming;
    int i = 0;
    unsigned long charge_full = 0;
    unsigned long charge_current = 0;
 
-   while (power->battery_names[i] != '\0')
+   while (i < power->battery_count)
      {
-        snprintf(path, sizeof(path), "/sys/class/power_supply/BAT%c", 
power->battery_names[i]);
+        naming = NULL;
+        snprintf(path, sizeof(path), "/sys/class/power_supply/%s", 
power->battery_names[i]);
+        if (stat(path, &st) < 0) continue;
+
+        if (S_ISLNK(st.st_mode)) continue;
+        if (!S_ISDIR(st.st_mode)) continue;
+
         dir = opendir(path);
         if (!dir) return;
         while ((dh = readdir(dir)) != NULL)
           {
-             if (!strcmp(dh->d_name, "energy_full"))
+             char *e;
+             if (dh->d_name[0] == '.') continue;
+             if ((e = strstr(dh->d_name, "_full\0")))
                {
-                  naming = "energy"; break;
-               }
-             else if (!strcmp(dh->d_name, "capacity_full"))
-               {
-                  naming = "capacity"; break;
+                  naming = strndup(dh->d_name, e - dh->d_name);
+                  break;
                }
           }
         closedir(dir);
+
         if (!naming) continue;
-        snprintf(path, sizeof(path), "/sys/class/power_supply/BAT%c/%s_full", 
power->battery_names[i], naming);
+        snprintf(path, sizeof(path), "/sys/class/power_supply/%s/%s_full", 
power->battery_names[i], naming);
         buf = Fcontents(path);
         if (buf)
           {
              charge_full = atol(buf);
              free(buf);
           }
-        snprintf(path, sizeof(path), "/sys/class/power_supply/BAT%c/%s_now", 
power->battery_names[i], naming);
+        snprintf(path, sizeof(path), "/sys/class/power_supply/%s/%s_now", 
power->battery_names[i], naming);
         buf = Fcontents(path);
         if (buf)
           {
@@ -1110,7 +1125,8 @@ _battery_state_get(power_t *power, int *mib)
           }
         power->batteries[i]->charge_full = charge_full;
         power->batteries[i]->charge_current = charge_current;
-        naming = NULL;
+
+        free(naming);
         i++;
      }
 #endif
@@ -1176,7 +1192,12 @@ _power_state_get(power_t *power)
 
 #endif
    for (i = 0; i < power->battery_count; i++)
-     if (power->bat_mibs[i]) free(power->bat_mibs[i]);
+     {
+        if (power->bat_mibs[i])
+          free(power->bat_mibs[i]);
+        if (power->battery_names[i])
+          free(power->battery_names[i]);
+     }
 }
 
 #if defined(__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__)
@@ -1691,6 +1712,8 @@ main(int argc, char **argv)
      {
        for (i = 0; i < results.power.battery_count; i++)
           free(results.power.batteries[i]);
+       if (results.power.batteries)
+          free(results.power.batteries);
      }
 
    if (flags & RESULTS_CPU)

-- 


Reply via email to