Line data Source code
1 : /**
2 : * Progress bar to give updates for operations in gfs2-utils.
3 : * Adapted from the simple progress bar in e2fsprogs progress.c
4 : *
5 : */
6 :
7 : #include <stdio.h>
8 : #include <string.h>
9 : #include <inttypes.h>
10 : #include <unistd.h>
11 : #include <time.h>
12 :
13 : #include "progress.h"
14 :
15 : static char spaces[44], backspaces[44];
16 : static time_t last_update;
17 :
18 142 : static int number_of_digits(int value)
19 : {
20 142 : int digits = 0;
21 :
22 : do {
23 213 : value /= 10;
24 213 : digits++;
25 213 : } while (value != 0);
26 :
27 142 : return digits;
28 : }
29 :
30 142 : void gfs2_progress_init(struct gfs2_progress_bar *progress, uint64_t max, const char *message, int quiet)
31 : {
32 : /**
33 : * NOTE:
34 : *
35 : * Default operation is to output the progress indication
36 : * in full. Although we will honor the quiet flag in the
37 : * application, if this is set we skip progress bar any
38 : * update operations and output.
39 : *
40 : */
41 :
42 142 : memset(spaces, ' ', sizeof(spaces)-1);
43 142 : spaces[sizeof(spaces)-1] = 0;
44 :
45 142 : memset(backspaces, '\b', sizeof(backspaces)-1);
46 142 : backspaces[sizeof(backspaces)-1] = 0;
47 :
48 142 : memset(progress, 0, sizeof(*progress));
49 :
50 142 : if (quiet) {
51 0 : progress->skip_progress++;
52 0 : return;
53 : }
54 :
55 142 : progress->max = max;
56 142 : progress->max_digits = number_of_digits(max);
57 :
58 142 : if (message) {
59 142 : fputs(message, stdout);
60 142 : fflush(stdout);
61 : }
62 142 : last_update = 0;
63 : }
64 :
65 6510 : void gfs2_progress_update(struct gfs2_progress_bar *progress, uint64_t value)
66 : {
67 : time_t current_time;
68 :
69 6510 : if (progress->skip_progress || (!isatty(STDOUT_FILENO)))
70 6510 : return;
71 :
72 0 : current_time = time(NULL);
73 0 : if (current_time == last_update)
74 0 : return;
75 0 : last_update = current_time;
76 :
77 0 : printf("[%*"PRIu64"/%*"PRIu64"]", progress->max_digits, value,
78 : progress->max_digits, progress->max);
79 0 : fflush(stdout);
80 0 : fprintf(stdout, "%.*s", (2 * progress->max_digits) + 3, backspaces);
81 : }
82 :
83 142 : void gfs2_progress_close(struct gfs2_progress_bar *progress, const char *message)
84 : {
85 142 : if (progress->skip_progress)
86 0 : return;
87 :
88 142 : if (isatty(STDOUT_FILENO)) {
89 0 : fprintf(stdout, "%.*s", (2 * progress->max_digits) + 3, spaces);
90 0 : fprintf(stdout, "%.*s", (2 * progress->max_digits) + 3, backspaces);
91 : }
92 :
93 142 : if (message)
94 142 : fputs(message, stdout);
95 : }
|