1 #include "git-compat-util.h"
4 static volatile sig_atomic_t progress_update
;
6 static void progress_interval(int signum
)
11 static void set_progress_signal(void)
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
);
38 int display_progress(struct progress
*progress
, unsigned n
)
40 if (progress
->delay
) {
42 if (!progress_update
|| --progress
->delay
)
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();
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
);
65 progress
->need_lf
= 1;
68 } else if (progress_update
) {
69 fprintf(stderr
, "%s%u\r", progress
->prefix
, n
);
71 progress
->need_lf
= 1;
77 void start_progress(struct progress
*progress
, const char *title
,
78 const char *prefix
, unsigned total
)
81 progress
->prefix
= prefix
;
82 progress
->total
= total
;
83 progress
->last_percent
= -1;
85 progress
->need_lf
= 0;
86 if (snprintf(buf
, sizeof(buf
), title
, total
))
87 fprintf(stderr
, "%s\n", buf
);
88 set_progress_signal();
91 void start_progress_delay(struct progress
*progress
, const char *title
,
92 const char *prefix
, unsigned total
,
93 unsigned percent_treshold
, unsigned delay
)
95 progress
->prefix
= prefix
;
96 progress
->total
= total
;
97 progress
->last_percent
= -1;
98 progress
->delayed_percent_treshold
= percent_treshold
;
99 progress
->delayed_title
= title
;
100 progress
->delay
= delay
;
101 progress
->need_lf
= 0;
102 set_progress_signal();
105 void stop_progress(struct progress
*progress
)
107 clear_progress_signal();
108 if (progress
->need_lf
)