Merge branch 'maint'
[git/jnareb-git/bp-gitweb.git] / progress.c
blob05f7890314e0bd596eb2e4110cdb98eeea61c9da
1 #include "git-compat-util.h"
2 #include "progress.h"
4 static volatile sig_atomic_t progress_update;
6 static void progress_interval(int signum)
8 progress_update = 1;
11 static void set_progress_signal(void)
13 struct sigaction sa;
14 struct itimerval v;
16 progress_update = 0;
18 memset(&sa, 0, sizeof(sa));
19 sa.sa_handler = progress_interval;
20 sigemptyset(&sa.sa_mask);
21 sa.sa_flags = SA_RESTART;
22 sigaction(SIGALRM, &sa, NULL);
24 v.it_interval.tv_sec = 1;
25 v.it_interval.tv_usec = 0;
26 v.it_value = v.it_interval;
27 setitimer(ITIMER_REAL, &v, NULL);
30 static void clear_progress_signal(void)
32 struct itimerval v = {{0,},};
33 setitimer(ITIMER_REAL, &v, NULL);
34 signal(SIGALRM, SIG_IGN);
35 progress_update = 0;
38 int display_progress(struct progress *progress, unsigned n)
40 if (progress->delay) {
41 char buf[80];
42 if (!progress_update || --progress->delay)
43 return 0;
44 if (progress->total) {
45 unsigned percent = n * 100 / progress->total;
46 if (percent > progress->delayed_percent_treshold) {
47 /* inhibit this progress report entirely */
48 clear_progress_signal();
49 progress->delay = -1;
50 progress->total = 0;
51 return 0;
54 if (snprintf(buf, sizeof(buf),
55 progress->delayed_title, progress->total))
56 fprintf(stderr, "%s\n", buf);
58 if (progress->total) {
59 unsigned percent = n * 100 / progress->total;
60 if (percent != progress->last_percent || progress_update) {
61 progress->last_percent = percent;
62 fprintf(stderr, "%s%4u%% (%u/%u) done\r",
63 progress->prefix, percent, n, progress->total);
64 progress_update = 0;
65 return 1;
67 } else if (progress_update) {
68 fprintf(stderr, "%s%u\r", progress->prefix, n);
69 progress_update = 0;
70 return 1;
72 return 0;
75 void start_progress(struct progress *progress, const char *title,
76 const char *prefix, unsigned total)
78 char buf[80];
79 progress->prefix = prefix;
80 progress->total = total;
81 progress->last_percent = -1;
82 progress->delay = 0;
83 if (snprintf(buf, sizeof(buf), title, total))
84 fprintf(stderr, "%s\n", buf);
85 set_progress_signal();
88 void start_progress_delay(struct progress *progress, const char *title,
89 const char *prefix, unsigned total,
90 unsigned percent_treshold, unsigned delay)
92 progress->prefix = prefix;
93 progress->total = total;
94 progress->last_percent = -1;
95 progress->delayed_percent_treshold = percent_treshold;
96 progress->delayed_title = title;
97 progress->delay = delay;
98 set_progress_signal();
101 void stop_progress(struct progress *progress)
103 clear_progress_signal();
104 if (progress->total)
105 fputc('\n', stderr);