summaryrefslogtreecommitdiff
path: root/src/charts.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2019-09-23 18:03:40 -0700
committerVito Caputo <vcaputo@pengaru.com>2019-09-23 18:03:40 -0700
commit4c9a16f4efe7fe2af2f418f8c668e51626eaf702 (patch)
tree2e7cd4a670a0df3e9da3b415b5138a7a17e5cb25 /src/charts.c
parent8f241509d127f114f46c95769c0ec66e51be222b (diff)
charts: introduce snprintf helper snpf()
Cleanup previous commit that littered MIN length clamping everywhere %n was being used w/snprintf. Removed the %n usage altogether and just clamps the return value out of snprintf to the buffer size minus one for the null terminator. The standard C library has such awful warts :/
Diffstat (limited to 'src/charts.c')
-rw-r--r--src/charts.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/src/charts.c b/src/charts.c
index 628b87a..da53992 100644
--- a/src/charts.c
+++ b/src/charts.c
@@ -24,6 +24,7 @@
#include <X11/extensions/Xrender.h>
#include <assert.h>
#include <math.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <sys/time.h>
@@ -122,6 +123,20 @@ static XRenderPictureAttributes pa_repeat = { .repeat = 1 };
static XRenderPictureAttributes pa_no_repeat = { .repeat = 0 };
+/* wrapper around snprintf always returning the length of what's in the buf */
+static int snpf(char *str, size_t size, const char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = vsnprintf(str, size, format, ap);
+ va_end(ap);
+
+ return MIN(ret, size - 1);
+}
+
+
/* this callback gets invoked at sample time once "per sys" */
static void sample_callback(vmon_t *vmon, void *arg)
{
@@ -581,16 +596,15 @@ static void draw_heirarchy_row(vwm_charts_t *charts, vwm_chart_t *chart, vmon_pr
/* put the process' wchan, state, and PID columns @ the far right */
if (proc->is_thread || list_empty(&proc->threads)) { /* only threads or non-threaded processes include the wchan and state */
- snprintf(str, sizeof(str), " %.*s %5i %c %n",
- proc_stat->wchan.len,
- proc_stat->wchan.len == 1 && proc_stat->wchan.array[0] == '0' ? "-" : proc_stat->wchan.array,
- proc->pid,
- proc_stat->state,
- &str_len);
+ str_len = snpf(str, sizeof(str), " %.*s %5i %c ",
+ proc_stat->wchan.len,
+ proc_stat->wchan.len == 1 && proc_stat->wchan.array[0] == '0' ? "-" : proc_stat->wchan.array,
+ proc->pid,
+ proc_stat->state);
} else { /* we're a process having threads, suppress the wchan and state, as they will be displayed for the thread of same pid */
- snprintf(str, sizeof(str), " %5i %n", proc->pid, &str_len);
+ str_len = snpf(str, sizeof(str), " %5i ", proc->pid);
}
- str_len = MIN(sizeof(str) - 1, str_len);
+
str_width = XTextWidth(charts->chart_font, str, str_len);
/* the process' comm label indented according to depth, followed with their respective argv's */
@@ -829,8 +843,7 @@ static void draw_chart(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_t *pr
/* only draw the \/\/\ and HZ if necessary */
if (chart->redraw_needed || charts->prev_sampling_interval != charts->sampling_interval) {
- snprintf(str, sizeof(str), "\\/\\/\\ %2iHz %n", (int)(charts->sampling_interval == INFINITY ? 0 : 1 / charts->sampling_interval), &str_len);
- str_len = MIN(sizeof(str) - 1, str_len);
+ str_len = snpf(str, sizeof(str), "\\/\\/\\ %2iHz ", (int)(charts->sampling_interval == INFINITY ? 0 : 1 / charts->sampling_interval));
XRenderFillRectangle(xserver->display, PictOpSrc, chart->text_picture, &chart_trans_color,
0, 0, /* dst x, y */
chart->visible_width, CHART_ROW_HEIGHT); /* dst w, h */
© All Rights Reserved