slstatus-dyn_battery-20250416-f68f492.diff (4427B)
1 From 44fcd213f975ae35fb92de9bc56d8d895478edb5 Mon Sep 17 00:00:00 2001 2 From: Madison Lynch <madi@mxdi.xyz> 3 Date: Wed, 16 Apr 2025 16:18:33 -0700 4 Subject: [PATCH] Improved memory-safety in dyn_battery function 5 6 --- 7 Makefile | 1 + 8 components/dyn_battery.c | 84 ++++++++++++++++++++++++++++++++++++++++ 9 config.def.h | 3 ++ 10 slstatus.h | 3 ++ 11 4 files changed, 91 insertions(+) 12 create mode 100644 components/dyn_battery.c 13 14 diff --git a/Makefile b/Makefile 15 index 7a18274..d1b24dd 100644 16 --- a/Makefile 17 +++ b/Makefile 18 @@ -11,6 +11,7 @@ COM =\ 19 components/cpu\ 20 components/datetime\ 21 components/disk\ 22 + components/dyn_battery\ 23 components/entropy\ 24 components/hostname\ 25 components/ip\ 26 diff --git a/components/dyn_battery.c b/components/dyn_battery.c 27 new file mode 100644 28 index 0000000..9377071 29 --- /dev/null 30 +++ b/components/dyn_battery.c 31 @@ -0,0 +1,84 @@ 32 +/* Written by Madison Lynch <madi@mxdi.xyz> */ 33 +/* Only Linux is supported */ 34 +#include <stdio.h> 35 +#include <stdlib.h> 36 +#include <string.h> 37 +#include <dirent.h> 38 + 39 +#include "../slstatus.h" 40 + 41 +#define BAT_PREFIX "BAT" 42 +#define BAT_DIR "/sys/class/power_supply" 43 + 44 +/** 45 +* Counts number of batteries detected by system. 46 +* 47 +* @return unsigned integer denoting the number of detected batteries. 48 +* @author Madison Lynch 49 +*/ 50 +static unsigned int 51 +battery_count(void) { 52 + DIR *dir = opendir(BAT_DIR); 53 + unsigned int bat_c = 0; 54 + 55 + struct dirent *entry; 56 + while((entry = readdir(dir))) 57 + if(strlen(entry->d_name) > 3) 58 + if(strncmp(entry->d_name, BAT_PREFIX, 3) == 0) 59 + bat_c++; 60 + 61 + (void) closedir(dir); 62 + return bat_c; 63 +} 64 + 65 +/** 66 +* Displays the status and capacity of a dynamic amount of batteries (i.e. 67 +* laptop may have secondary external battery). 68 +* 69 +* @param fmt format string to use for each battery display. ordered key: 70 +* %u: battery number || %s: battery state || %s battery capacity 71 +* @return string containing the status and capacities of all detected batteries 72 +* @author Madison Lynch 73 +*/ 74 +const char * 75 +dyn_battery(const char *fmt) { 76 + static char *ret; 77 + free(ret); // Free address from previous output 78 + 79 + const size_t fmt_s = strlen(fmt); 80 + const unsigned int bat_c = battery_count(); 81 + 82 + // Extra byte in calloc() for null byte 83 + ret = (char *)calloc(fmt_s * bat_c + 1, sizeof(char)); 84 + if(!ret) { 85 + fprintf(stderr, "dyn_battery: calloc() failed."); 86 + return NULL; 87 + } 88 + 89 + unsigned int displacement = 0; // For appending battery displays 90 + for(unsigned int i=0; i<bat_c; i++) { 91 + char bat[7]; // "BAT" = 3 + <=3 digit number + null byte 92 + (void) sprintf(bat, "BAT%u", i); 93 + 94 + // Add battery display to final string to be returned 95 + (void) sprintf( 96 + ret + displacement, 97 + fmt, 98 + i, 99 + battery_state(bat), 100 + battery_perc(bat) 101 + ); 102 + displacement = strlen(ret); 103 + 104 + // Add space between battery displays 105 + ret[displacement++] = ' '; 106 + } 107 + 108 + // Remove extra space after last battery display 109 + ret[--displacement] = '\0'; 110 + 111 + return ret; 112 +} 113 + 114 +#undef BAT_DIR 115 +#undef BAT_PREFIX 116 diff --git a/config.def.h b/config.def.h 117 index d805331..a0052e3 100644 118 --- a/config.def.h 119 +++ b/config.def.h 120 @@ -26,6 +26,9 @@ static const char unknown_str[] = "n/a"; 121 * disk_perc disk usage in percent mountpoint path (/) 122 * disk_total total disk space in GB mountpoint path (/) 123 * disk_used used disk space in GB mountpoint path (/) 124 + * dyn_battery displays the name, state and format string (%u, %s, 125 + * capacity of all detected %s). order is important, 126 + * batteries and matches description. 127 * entropy available entropy NULL 128 * gid GID of current user NULL 129 * hostname hostname NULL 130 diff --git a/slstatus.h b/slstatus.h 131 index 8ef5874..44a4b61 100644 132 --- a/slstatus.h 133 +++ b/slstatus.h 134 @@ -21,6 +21,9 @@ const char *disk_perc(const char *path); 135 const char *disk_total(const char *path); 136 const char *disk_used(const char *path); 137 138 +/* dyn_battery */ 139 +const char *dyn_battery(const char *fmt); 140 + 141 /* entropy */ 142 const char *entropy(const char *unused); 143 144 -- 145 2.49.0 146