slstatus-dyn_battery-20250416-f68f492.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       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