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
);
67 } else if (progress_update
) {
68 fprintf(stderr
, "%s%u\r", progress
->prefix
, n
);
75 void start_progress(struct progress
*progress
, const char *title
,
76 const char *prefix
, unsigned total
)
79 progress
->prefix
= prefix
;
80 progress
->total
= total
;
81 progress
->last_percent
= -1;
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();