void stop_progress_msg(struct progress **p_progress, const char *msg) { struct progress *progress = *p_progress; if (!progress) return; *p_progress = NULL; if (progress->last_value != -1) { /* Force the last update */ char buf[128], *bufp; size_t len = strlen(msg) + 5; struct throughput *tp = progress->throughput; bufp = (len < sizeof(buf)) ? buf : xmalloc(len + 1); if (tp) { struct strbuf strbuf = STRBUF_INIT; unsigned int rate = !tp->avg_misecs ? 0 : tp->avg_bytes / tp->avg_misecs; throughput_string(&strbuf, tp->curr_total, rate); strncpy(tp->display, strbuf.buf, sizeof(tp->display)); strbuf_release(&strbuf); } progress_update = 1; sprintf(bufp, ", %s.\n", msg); display(progress, progress->last_value, bufp); if (buf != bufp) free(bufp); } clear_progress_signal(); free(progress->throughput); free(progress); }
static int display(struct progress *progress, unsigned n, const char *done) { const char *eol, *tp; if (progress->delay) { if (!progress_update || --progress->delay) return 0; if (progress->total) { unsigned percent = n * 100 / progress->total; if (percent > progress->delayed_percent_threshold) { /* inhibit this progress report entirely */ clear_progress_signal(); progress->delay = -1; progress->total = 0; return 0; } } } progress->last_value = n; tp = (progress->throughput) ? progress->throughput->display.buf : ""; eol = done ? done : " \r"; if (progress->total) { unsigned percent = n * 100 / progress->total; if (percent != progress->last_percent || progress_update) { progress->last_percent = percent; if (is_foreground_fd(fileno(stderr)) || done) { fprintf(stderr, "%s: %3u%% (%u/%u)%s%s", progress->title, percent, n, progress->total, tp, eol); fflush(stderr); } progress_update = 0; return 1; } } else if (progress_update) { if (is_foreground_fd(fileno(stderr)) || done) { fprintf(stderr, "%s: %u%s%s", progress->title, n, tp, eol); fflush(stderr); } progress_update = 0; return 1; } return 0; }