From 4c9a16f4efe7fe2af2f418f8c668e51626eaf702 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 23 Sep 2019 18:03:40 -0700 Subject: 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 :/ --- src/charts.c | 33 +++++++++++++++++++++++---------- 1 file 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 #include #include +#include #include #include @@ -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 */ -- cgit v1.2.3