diff --git a/src/import/export-raw.c b/src/import/export-raw.c index 337d74706a..5e34fd372e 100644 --- a/src/import/export-raw.c +++ b/src/import/export-raw.c @@ -124,17 +124,14 @@ static void raw_export_report_progress(RawExport *e) { sd_notifyf(false, "X_IMPORT_PROGRESS=%u%%", percent); - if (isatty_safe(STDERR_FILENO)) { - _cleanup_free_ char *s = NULL; - - if (asprintf(&s, "%s %s/%s", - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), - FORMAT_BYTES(e->written_uncompressed), - FORMAT_BYTES(e->st.st_size)) < 0) - return; - - draw_progress_bar(s, percent); - } else + if (isatty_safe(STDERR_FILENO)) + (void) draw_progress_barf( + percent, + "%s %s/%s", + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), + FORMAT_BYTES(e->written_uncompressed), + FORMAT_BYTES(e->st.st_size)); + else log_info("Exported %u%%.", percent); e->last_percent = percent; diff --git a/src/import/export-tar.c b/src/import/export-tar.c index 42f3adee96..e025efe411 100644 --- a/src/import/export-tar.c +++ b/src/import/export-tar.c @@ -134,17 +134,14 @@ static void tar_export_report_progress(TarExport *e) { sd_notifyf(false, "X_IMPORT_PROGRESS=%u%%", percent); - if (isatty_safe(STDERR_FILENO)) { - _cleanup_free_ char *s = NULL; - - if (asprintf(&s, "%s %s/%s", - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), - FORMAT_BYTES(e->written_uncompressed), - FORMAT_BYTES(e->quota_referenced)) < 0) - return; - - draw_progress_bar(s, percent); - } else + if (isatty_safe(STDERR_FILENO)) + (void) draw_progress_barf( + percent, + "%s %s/%s", + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), + FORMAT_BYTES(e->written_uncompressed), + FORMAT_BYTES(e->quota_referenced)); + else log_info("Exported %u%%.", percent); e->last_percent = percent; diff --git a/src/import/import-raw.c b/src/import/import-raw.c index 190a08a005..602d1f1ac3 100644 --- a/src/import/import-raw.c +++ b/src/import/import-raw.c @@ -151,17 +151,14 @@ static void raw_import_report_progress(RawImport *i) { sd_notifyf(false, "X_IMPORT_PROGRESS=%u%%", percent); - if (isatty_safe(STDERR_FILENO)) { - _cleanup_free_ char *s = NULL; - - if (asprintf(&s, "%s %s/%s", - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), - FORMAT_BYTES(i->written_compressed), - FORMAT_BYTES(i->input_stat.st_size)) < 0) - return; - - draw_progress_bar(s, percent); - } else + if (isatty_safe(STDERR_FILENO)) + (void) draw_progress_barf( + percent, + "%s %s/%s", + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), + FORMAT_BYTES(i->written_compressed), + FORMAT_BYTES(i->input_stat.st_size)); + else log_info("Imported %u%%.", percent); i->last_percent = percent; diff --git a/src/import/import-tar.c b/src/import/import-tar.c index 6e6c720782..e82159cb52 100644 --- a/src/import/import-tar.c +++ b/src/import/import-tar.c @@ -152,17 +152,14 @@ static void tar_import_report_progress(TarImport *i) { sd_notifyf(false, "X_IMPORT_PROGRESS=%u%%", percent); - if (isatty_safe(STDERR_FILENO)) { - _cleanup_free_ char *s = NULL; - - if (asprintf(&s, "%s %s/%s", - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), - FORMAT_BYTES(i->written_compressed), - FORMAT_BYTES(i->input_stat.st_size)) < 0) - return; - - draw_progress_bar(s, percent); - } else + if (isatty_safe(STDERR_FILENO)) + (void) draw_progress_barf( + percent, + "%s %s/%s", + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), + FORMAT_BYTES(i->written_compressed), + FORMAT_BYTES(i->input_stat.st_size)); + else log_info("Imported %u%%.", percent); i->last_percent = percent; diff --git a/src/partition/repart.c b/src/partition/repart.c index 1acd5af38c..5427e0a69f 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -5085,21 +5085,19 @@ static int partition_format_verity_sig(Context *context, Partition *p) { static int progress_bytes(uint64_t n_bytes, void *userdata) { Partition *p = ASSERT_PTR(userdata); - _cleanup_free_ char *s = NULL; p->copy_blocks_done += n_bytes; - if (asprintf(&s, "%s %s %s %s/%s", - strna(p->copy_blocks_path), - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), - strna(p->definition_path), - FORMAT_BYTES(p->copy_blocks_done), - FORMAT_BYTES(p->copy_blocks_size)) < 0) - return log_oom(); + (void) draw_progress_barf( + p->copy_blocks_done >= p->copy_blocks_size ? 100.0 : /* catch division be zero */ + 100.0 * (double) p->copy_blocks_done / (double) p->copy_blocks_size, + "%s %s %s %s/%s", + strna(p->copy_blocks_path), + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), + strna(p->definition_path), + FORMAT_BYTES(p->copy_blocks_done), + FORMAT_BYTES(p->copy_blocks_size)); - draw_progress_bar(s, - p->copy_blocks_done >= p->copy_blocks_size ? 100.0 : /* catch division be zero */ - 100.0 * (double) p->copy_blocks_done / (double) p->copy_blocks_size); return 0; } diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c index 322d5f496d..df1c20fa24 100644 --- a/src/shared/pretty-print.c +++ b/src/shared/pretty-print.c @@ -461,7 +461,7 @@ bool shall_tint_background(void) { return cache != 0; } -void draw_progress_bar_impl(const char *prefix, double percentage) { +void draw_progress_bar_unbuffered(const char *prefix, double percentage) { fputc('\r', stderr); if (prefix) { fputs(prefix, stderr); @@ -522,10 +522,9 @@ void draw_progress_bar_impl(const char *prefix, double percentage) { fputs(ANSI_ERASE_TO_END_OF_LINE, stderr); fputc('\r', stderr); - } -void clear_progress_bar_impl(const char *prefix) { +void clear_progress_bar_unbuffered(const char *prefix) { fputc('\r', stderr); if (terminal_is_dumb()) @@ -546,10 +545,26 @@ void draw_progress_bar(const char *prefix, double percentage) { * unbuffered by default. Let's temporarily turn on full buffering, so that this is passed to the tty * as a single buffer, to make things more efficient. */ WITH_BUFFERED_STDERR; - draw_progress_bar_impl(prefix, percentage); + draw_progress_bar_unbuffered(prefix, percentage); +} + +int draw_progress_barf(double percentage, const char *prefixf, ...) { + _cleanup_free_ char *s = NULL; + va_list ap; + int r; + + va_start(ap, prefixf); + r = vasprintf(&s, prefixf, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + draw_progress_bar(s, percentage); + return 0; } void clear_progress_bar(const char *prefix) { WITH_BUFFERED_STDERR; - clear_progress_bar_impl(prefix); + clear_progress_bar_unbuffered(prefix); } diff --git a/src/shared/pretty-print.h b/src/shared/pretty-print.h index 446f305b73..8ea1e964a3 100644 --- a/src/shared/pretty-print.h +++ b/src/shared/pretty-print.h @@ -54,9 +54,10 @@ int terminal_tint_color(double hue, char **ret); bool shall_tint_background(void); void draw_progress_bar(const char *prefix, double percentage); +int draw_progress_barf(double percentage, const char *prefixf, ...) _printf_(2, 3); void clear_progress_bar(const char *prefix); -void draw_progress_bar_impl(const char *prefix, double percentage); -void clear_progress_bar_impl(const char *prefix); +void draw_progress_bar_unbuffered(const char *prefix, double percentage); +void clear_progress_bar_unbuffered(const char *prefix); static inline FILE* enable_buffering(FILE *f, char *buffer, size_t size) { assert(f); diff --git a/src/sysupdate/updatectl.c b/src/sysupdate/updatectl.c index e7e4b374da..7cfccb66f4 100644 --- a/src/sysupdate/updatectl.c +++ b/src/sysupdate/updatectl.c @@ -843,23 +843,23 @@ static int update_render_progress(sd_event_source *source, void *userdata) { int progress = PTR_TO_INT(p); if (progress == UPDATE_PROGRESS_FAILED) { - clear_progress_bar_impl(target); + clear_progress_bar_unbuffered(target); fprintf(stderr, "%s: %s Unknown failure\n", target, RED_CROSS_MARK()); total += 100; } else if (progress == -EALREADY) { - clear_progress_bar_impl(target); + clear_progress_bar_unbuffered(target); fprintf(stderr, "%s: %s Already up-to-date\n", target, GREEN_CHECK_MARK()); n--; /* Don't consider this target in the total */ } else if (progress < 0) { - clear_progress_bar_impl(target); + clear_progress_bar_unbuffered(target); fprintf(stderr, "%s: %s %s\n", target, RED_CROSS_MARK(), STRERROR(progress)); total += 100; } else if (progress == UPDATE_PROGRESS_DONE) { - clear_progress_bar_impl(target); + clear_progress_bar_unbuffered(target); fprintf(stderr, "%s: %s Done\n", target, GREEN_CHECK_MARK()); total += 100; } else { - draw_progress_bar_impl(target, progress); + draw_progress_bar_unbuffered(target, progress); fputs("\n", stderr); total += progress; } @@ -867,9 +867,9 @@ static int update_render_progress(sd_event_source *source, void *userdata) { if (n > 1) { if (exiting) - clear_progress_bar_impl(target); + clear_progress_bar_unbuffered(target); else { - draw_progress_bar_impl("Total", (double) total / n); + draw_progress_bar_unbuffered("Total", (double) total / n); if (terminal_is_dumb()) fputs("\n", stderr); } diff --git a/src/test/test-progress-bar.c b/src/test/test-progress-bar.c index abc1d292dc..b199741cf5 100644 --- a/src/test/test-progress-bar.c +++ b/src/test/test-progress-bar.c @@ -14,7 +14,7 @@ TEST(progress_bar) { for (double d = 0; d <= 100; d += 0.5) { usleep_safe(random_u64_range(20 * USEC_PER_MSEC)); - draw_progress_bar(PROGRESS_PREFIX, d); + draw_progress_barf(d, PROGRESS_PREFIX "[" PID_FMT "]", getpid_cached()); if (!paused && d >= 50) { clear_progress_bar(PROGRESS_PREFIX); @@ -25,9 +25,9 @@ TEST(progress_bar) { } } - draw_progress_bar(PROGRESS_PREFIX, 100); + draw_progress_barf(100, PROGRESS_PREFIX "[" PID_FMT "]", getpid_cached()); usleep_safe(300 * MSEC_PER_SEC); - clear_progress_bar(PROGRESS_PREFIX); + clear_progress_bar(PROGRESS_PREFIX "[0123456789]" ); fputs("Done.\n", stdout); }