From 44fcd213f975ae35fb92de9bc56d8d895478edb5 Mon Sep 17 00:00:00 2001 From: Madison Lynch Date: Wed, 16 Apr 2025 16:18:33 -0700 Subject: [PATCH] Improved memory-safety in dyn_battery function --- Makefile | 1 + components/dyn_battery.c | 84 ++++++++++++++++++++++++++++++++++++++++ config.def.h | 3 ++ slstatus.h | 3 ++ 4 files changed, 91 insertions(+) create mode 100644 components/dyn_battery.c diff --git a/Makefile b/Makefile index 7a18274..d1b24dd 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ COM =\ components/cpu\ components/datetime\ components/disk\ + components/dyn_battery\ components/entropy\ components/hostname\ components/ip\ diff --git a/components/dyn_battery.c b/components/dyn_battery.c new file mode 100644 index 0000000..9377071 --- /dev/null +++ b/components/dyn_battery.c @@ -0,0 +1,84 @@ +/* Written by Madison Lynch */ +/* Only Linux is supported */ +#include +#include +#include +#include + +#include "../slstatus.h" + +#define BAT_PREFIX "BAT" +#define BAT_DIR "/sys/class/power_supply" + +/** +* Counts number of batteries detected by system. +* +* @return unsigned integer denoting the number of detected batteries. +* @author Madison Lynch +*/ +static unsigned int +battery_count(void) { + DIR *dir = opendir(BAT_DIR); + unsigned int bat_c = 0; + + struct dirent *entry; + while((entry = readdir(dir))) + if(strlen(entry->d_name) > 3) + if(strncmp(entry->d_name, BAT_PREFIX, 3) == 0) + bat_c++; + + (void) closedir(dir); + return bat_c; +} + +/** +* Displays the status and capacity of a dynamic amount of batteries (i.e. +* laptop may have secondary external battery). +* +* @param fmt format string to use for each battery display. ordered key: +* %u: battery number || %s: battery state || %s battery capacity +* @return string containing the status and capacities of all detected batteries +* @author Madison Lynch +*/ +const char * +dyn_battery(const char *fmt) { + static char *ret; + free(ret); // Free address from previous output + + const size_t fmt_s = strlen(fmt); + const unsigned int bat_c = battery_count(); + + // Extra byte in calloc() for null byte + ret = (char *)calloc(fmt_s * bat_c + 1, sizeof(char)); + if(!ret) { + fprintf(stderr, "dyn_battery: calloc() failed."); + return NULL; + } + + unsigned int displacement = 0; // For appending battery displays + for(unsigned int i=0; i