From fe38da3d0afd8ced330b7450d28315e4a2b59cd2 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sun, 1 Oct 2023 12:37:57 +0000 Subject: [PATCH] cli: progressbar: Dynamically allocate all buffers Signed-off-by: Michael Tremer --- src/cli/lib/progressbar.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/cli/lib/progressbar.c b/src/cli/lib/progressbar.c index e793c557b..08bb02f08 100644 --- a/src/cli/lib/progressbar.c +++ b/src/cli/lib/progressbar.c @@ -51,7 +51,7 @@ struct cli_progressbar_widget { struct cli_progressbar_widget* widget, unsigned int width, void* data); void (*free)(void* data); - char buffer[1024]; + char* buffer; }; struct cli_progressbar { @@ -102,6 +102,9 @@ static void cli_progressbar_widget_free(struct cli_progressbar_widget* widget) { if (widget->free && widget->data) widget->free(widget->data); + if (widget->buffer) + free(widget->buffer); + free(widget); } @@ -327,7 +330,7 @@ static const char* cli_progressbar_counter(struct cli_progressbar* p, unsigned long int max_value = pakfire_progress_get_value(p->progress); // Format the result - r = snprintf(widget->buffer, sizeof(widget->buffer), "%lu/%lu", value, max_value); + r = asprintf(&widget->buffer, "%lu/%lu", value, max_value); if (r < 0) return NULL; @@ -346,7 +349,7 @@ static const char* cli_progressbar_percentage(struct cli_progressbar* p, double percentage = pakfire_progress_get_percentage(p->progress); // Format to string - r = snprintf(widget->buffer, sizeof(widget->buffer), "%3.0f%%", percentage); + r = asprintf(&widget->buffer, "%3.0f%%", percentage); if (r < 0) return NULL; @@ -359,7 +362,11 @@ static int cli_progressbar_add_percentage(struct cli_progressbar* p) { static const char* cli_progressbar_bar(struct cli_progressbar* p, struct cli_progressbar_widget* widget, unsigned int width, void* data) { - if (width >= sizeof(widget->buffer) || width < 2) + // Allocate or adjust the buffer + widget->buffer = realloc(widget->buffer, width); + + // Fail if we could not allocate the buffer + if (!widget->buffer) return NULL; // Remove the bar when we are finished so that the terminal is not so cluttered @@ -385,7 +392,7 @@ static const char* cli_progressbar_bar(struct cli_progressbar* p, widget->buffer[i] = '-'; } - // Terminat the string + // Terminate the string widget->buffer[width] = '\0'; return widget->buffer; @@ -405,7 +412,7 @@ static const char* cli_progressbar_elapsed_time(struct cli_progressbar* p, return NULL; // Format the time - r = snprintf(widget->buffer, sizeof(widget->buffer), "%02lu:%02lu", t / 60, t % 60); + r = asprintf(&widget->buffer, "%02lu:%02lu", t / 60, t % 60); if (r) return NULL; @@ -429,14 +436,13 @@ static const char* cli_progressbar_eta(struct cli_progressbar* p, // Print a placeholder when we have no ETA (yet) if (t <= 0) { - r = snprintf(widget->buffer, sizeof(widget->buffer), "%-5s: --:--:--", _("ETA")); + r = asprintf(&widget->buffer, "%-5s: --:--:--", _("ETA")); if (r < 0) return NULL; // Otherwise show the ETA } else { - r = snprintf(widget->buffer, sizeof(widget->buffer), "%-5s: %02lu:%02lu", - _("ETA"), t / 60, t % 60); + r = asprintf(&widget->buffer, "%-5s: %02lu:%02lu", _("ETA"), t / 60, t % 60); if (r < 0) return NULL; } @@ -448,10 +454,7 @@ static int cli_progressbar_add_eta(struct cli_progressbar* p) { return cli_progressbar_add_widget(p, cli_progressbar_eta, NULL, 0, NULL); } -#define cli_progressbar_format_speed(s, speed) \ - __cli_progressbar_format_speed(s, sizeof(s), speed) - -static int __cli_progressbar_format_speed(char* s, const size_t length, double value) { +static int cli_progressbar_format_speed(char** s, double value) { const char* units[] = { "%4.0fB/s", "%4.0fkB/s", @@ -469,7 +472,7 @@ static int __cli_progressbar_format_speed(char* s, const size_t length, double v } // Format the string - r = snprintf(s, length, *unit, value); + r = asprintf(s, *unit, value); if (r < 0) return r; @@ -524,7 +527,7 @@ static const char* cli_progressbar_bytes_transferred(struct cli_progressbar* p, return NULL; // Add padding so that the string is always at least five characters long - r = snprintf(widget->buffer, sizeof(widget->buffer), "%-5s", buffer); + r = asprintf(&widget->buffer, "%-5s", buffer); if (r < 0) return NULL; @@ -537,12 +540,15 @@ static int cli_progressbar_add_bytes_transferred(struct cli_progressbar* p) { static const char* cli_progressbar_transfer_speed(struct cli_progressbar* p, struct cli_progressbar_widget* widget, unsigned int width, void* data) { + int r; + + // Fetch the speed double speed = pakfire_progress_get_transfer_speed(p->progress); if (speed < 0) return NULL; // Format the speed - int r = cli_progressbar_format_speed(widget->buffer, speed); + r = cli_progressbar_format_speed(&widget->buffer, speed); if (r < 0) return NULL; -- 2.47.3