Implement esnprintf() and make formatted calls more efficient 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.
Laslo Hunhold dev@frign.de
Sat, 19 May 2018 19:33:04 +0200
6 files changed,
72 insertions(+),
23 deletions(-)
M
components/battery.c
→
components/battery.c
@@ -14,9 +14,16 @@ {
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 *@@ -32,8 +39,11 @@ };
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; }@@ -53,20 +63,29 @@ int charge_now, current_now, m, h;
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", ¤t_now) != 1) { return NULL; }
M
components/netspeeds.c
→
components/netspeeds.c
@@ -17,8 +17,11 @@ char path[PATH_MAX];
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; }@@ -37,8 +40,11 @@ char path[PATH_MAX];
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; }
M
components/wifi.c
→
components/wifi.c
@@ -23,8 +23,11 @@ char path[PATH_MAX];
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;@@ -69,7 +72,10 @@ struct iwreq wreq;
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':");
M
slstatus.c
→
slstatus.c
@@ -91,12 +91,8 @@ for (i = len = 0; i < LEN(args); i++) {
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;
M
util.c
→
util.c
@@ -48,6 +48,27 @@
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, ...) {