Implement esnprintf() and make formatted calls more efficient
authorLaslo Hunhold <dev@frign.de>
Sat, 19 May 2018 17:33:04 +0000 (19:33 +0200)
committerAaron Marcher <me@drkhsh.at>
Sat, 19 May 2018 17:44:02 +0000 (19:44 +0200)
Within the components, snprintf() was unchecked and had inefficient
calls in some places.
We implement esnprintf() that does all the dirty laundry for us
and use it exclusively now.

components/battery.c
components/netspeeds.c
components/wifi.c
slstatus.c
util.c
util.h

index 90e859070aaec4a51deeee647737939d6880fe88..bcd42cda413aac9b09aa1c2daff26559c68418d3 100644 (file)
                int perc;
                char path[PATH_MAX];
 
-               snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/",
-                        bat, "/capacity");
-               return (pscanf(path, "%d", &perc) == 1) ? bprintf("%d", perc) : NULL;
+               if (esnprintf(path, sizeof(path),
+                             "/sys/class/power_supply/%s/capacity",
+                             bat) < 0) {
+                       return NULL;
+               }
+               if (pscanf(path, "%d", &perc) != 1) {
+                       return NULL;
+               }
+
+               return bprintf("%d", perc);
        }
 
        const char *
                size_t i;
                char path[PATH_MAX], state[12];
 
-               snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/",
-                        bat, "/status");
+               if (esnprintf(path, sizeof(path),
+                             "/sys/class/power_supply/%s/status",
+                             bat) < 0) {
+                       return NULL;
+               }
                if (pscanf(path, "%12s", state) != 1) {
                        return NULL;
                }
                float timeleft;
                char path[PATH_MAX], state[12];
 
-               snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/",
-                        bat, "/status");
+               if (esnprintf(path, sizeof(path),
+                             "/sys/class/power_supply/%s/status",
+                             bat) < 0) {
+                       return NULL;
+               }
                if (pscanf(path, "%12s", state) != 1) {
                        return NULL;
                }
 
                if (!strcmp(state, "Discharging")) {
-                       snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/",
-                                        bat, "/charge_now");
+                       if (esnprintf(path, sizeof(path),
+                                      "/sys/class/power_supply/%s/charge_now",
+                                     bat) < 0) {
+                               return NULL;
+                       }
                        if (pscanf(path, "%d", &charge_now) != 1) {
                                return NULL;
                        }
-                       snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/",
-                                        bat, "/current_now");
+                       if (esnprintf(path, sizeof(path),
+                                     "/sys/class/power_supply/%s/current_now",
+                                     bat) < 0) {
+                               return NULL;
+                       }
                        if (pscanf(path, "%d", &current_now) != 1) {
                                return NULL;
                        }
index b4e6972133c9aae14fc70fd6f8c955c6ea2365cb..6adc3ea804fc5ed388bcb8bd38a776ffdc127d62 100644 (file)
 
                oldrxbytes = rxbytes;
 
-               snprintf(path, sizeof(path),
-                        "/sys/class/net/%s/statistics/rx_bytes", interface);
+               if (esnprintf(path, sizeof(path),
+                             "/sys/class/net/%s/statistics/rx_bytes",
+                             interface) < 0) {
+                       return NULL;
+               }
                if (pscanf(path, "%llu", &rxbytes) != 1) {
                        return NULL;
                }
 
                oldtxbytes = txbytes;
 
-               snprintf(path, sizeof(path),
-                        "/sys/class/net/%s/statistics/tx_bytes", interface);
+               if (esnprintf(path, sizeof(path),
+                             "/sys/class/net/%s/statistics/tx_bytes",
+                             interface) < 0) {
+                       return NULL;
+               }
                if (pscanf(path, "%llu", &txbytes) != 1) {
                        return NULL;
                }
index 591f6ad9fed8b4cb7caadc4a6107640081a1bad7..b3e1723bd9729e02672a95f05b2d8040ab84fe6a 100644 (file)
                char status[5];
                FILE *fp;
 
-               snprintf(path, sizeof(path), "%s%s%s", "/sys/class/net/", iface,
-                        "/operstate");
+               if (esnprintf(path, sizeof(path),
+                             "/sys/class/net/%s/operstate",
+                             iface) < 0) {
+                       return NULL;
+               }
                if (!(fp = fopen(path, "r"))) {
                        warn("fopen '%s':", path);
                        return NULL;
 
                memset(&wreq, 0, sizeof(struct iwreq));
                wreq.u.essid.length = IW_ESSID_MAX_SIZE+1;
-               snprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "%s", iface);
+               if (esnprintf(wreq.ifr_name, sizeof(wreq.ifr_name),
+                             "%s", iface) < 0) {
+                       return NULL;
+               }
 
                if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                        warn("socket 'AF_INET':");
index 0c4605fc9fe47dcb93746a027b57fed30e74cd44..3222b02375d06301e1347ccc7df992c4fac694bf 100644 (file)
@@ -91,12 +91,8 @@ main(int argc, char *argv[])
                        if (!(res = args[i].func(args[i].args))) {
                                res = unknown_str;
                        }
-                       if ((ret = snprintf(status + len, sizeof(status) - len,
+                       if ((ret = esnprintf(status + len, sizeof(status) - len,
                                            args[i].fmt, res)) < 0) {
-                               warn("snprintf:");
-                               break;
-                       } else if ((size_t)ret >= sizeof(status) - len) {
-                               warn("snprintf: Output truncated");
                                break;
                        }
                        len += ret;
diff --git a/util.c b/util.c
index a7576b4702583d508b604e7551f30961b2e02bd8..923d4df3524070b4a77ef55016ac313bafbad5c9 100644 (file)
--- a/util.c
+++ b/util.c
@@ -48,6 +48,27 @@ die(const char *fmt, ...)
        exit(1);
 }
 
+int
+esnprintf(char *str, size_t size, const char *fmt, ...)
+{
+       va_list ap;
+       int ret;
+
+       va_start(ap, fmt);
+       ret = vsnprintf(str, size, fmt, ap);
+       va_end(ap);
+
+       if (ret < 0) {
+               warn("snprintf:");
+               return -1;
+       } else if ((size_t)ret >= size) {
+               warn("snprintf: Output truncated");
+               return -1;
+       }
+
+       return ret;
+}
+
 const char *
 bprintf(const char *fmt, ...)
 {
diff --git a/util.h b/util.h
index bd05574b18108611ab446381ac8e761517f9698f..5111b377310579acf123cb4d21281a8e41edfc35 100644 (file)
--- a/util.h
+++ b/util.h
@@ -8,6 +8,7 @@ extern char *argv0;
 void warn(const char *, ...);
 void die(const char *, ...);
 
+int esnprintf(char *str, size_t size, const char *fmt, ...);
 const char *bprintf(const char *fmt, ...);
 const char *fmt_scaled(size_t);
 int pscanf(const char *path, const char *fmt, ...);