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 140 : static int number_of_digits(int value) 19 : { 20 140 : int digits = 0; 21 : 22 : do { 23 210 : value /= 10; 24 210 : digits++; 25 210 : } while (value != 0); 26 : 27 140 : return digits; 28 : } 29 : 30 140 : 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 140 : memset(spaces, ' ', sizeof(spaces)-1); 43 140 : spaces[sizeof(spaces)-1] = 0; 44 : 45 140 : memset(backspaces, '\b', sizeof(backspaces)-1); 46 140 : backspaces[sizeof(backspaces)-1] = 0; 47 : 48 140 : memset(progress, 0, sizeof(*progress)); 49 : 50 140 : if (quiet) { 51 0 : progress->skip_progress++; 52 0 : return; 53 : } 54 : 55 140 : progress->max = max; 56 140 : progress->max_digits = number_of_digits(max); 57 : 58 140 : if (message) { 59 140 : fputs(message, stdout); 60 140 : fflush(stdout); 61 : } 62 140 : last_update = 0; 63 : } 64 : 65 6429 : void gfs2_progress_update(struct gfs2_progress_bar *progress, uint64_t value) 66 : { 67 : time_t current_time; 68 : 69 6429 : if (progress->skip_progress || (!isatty(STDOUT_FILENO))) 70 6429 : 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 140 : void gfs2_progress_close(struct gfs2_progress_bar *progress, const char *message) 84 : { 85 140 : if (progress->skip_progress) 86 0 : return; 87 : 88 140 : 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 140 : if (message) 94 140 : fputs(message, stdout); 95 : }