sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | 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