diff options
Diffstat (limited to 'libbb/progress.c')
-rw-r--r-- | libbb/progress.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/libbb/progress.c b/libbb/progress.c index e96039042..f53271398 100644 --- a/libbb/progress.c +++ b/libbb/progress.c | |||
@@ -66,16 +66,29 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
66 | off_t transferred, | 66 | off_t transferred, |
67 | off_t totalsize) | 67 | off_t totalsize) |
68 | { | 68 | { |
69 | off_t abbrevsize; | 69 | uoff_t beg_and_transferred; |
70 | unsigned since_last_update, elapsed; | 70 | unsigned since_last_update, elapsed; |
71 | unsigned ratio; | 71 | unsigned ratio; |
72 | int barlength, i; | 72 | int barlength, i; |
73 | 73 | ||
74 | /* totalsize == 0 if it is unknown */ | ||
75 | |||
76 | elapsed = monotonic_sec(); | ||
77 | since_last_update = elapsed - p->lastupdate_sec; | ||
78 | /* Do not update on every call | ||
79 | * (we can be called on every network read!) */ | ||
80 | if (since_last_update == 0 && !totalsize) | ||
81 | return; | ||
82 | |||
83 | beg_and_transferred = beg_range + transferred; | ||
74 | ratio = 100; | 84 | ratio = 100; |
75 | if (totalsize) { | 85 | if (beg_and_transferred < totalsize) { |
86 | /* Do not update on every call | ||
87 | * (we can be called on every network read!) */ | ||
88 | if (since_last_update == 0) | ||
89 | return; | ||
76 | /* long long helps to have it working even if !LFS */ | 90 | /* long long helps to have it working even if !LFS */ |
77 | ratio = (unsigned) (100ULL * (transferred+beg_range) / totalsize); | 91 | ratio = 100ULL * beg_and_transferred / (uoff_t)totalsize; |
78 | if (ratio > 100) ratio = 100; | ||
79 | } | 92 | } |
80 | 93 | ||
81 | #if ENABLE_UNICODE_SUPPORT | 94 | #if ENABLE_UNICODE_SUPPORT |
@@ -95,35 +108,33 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
95 | /* back to multibyte; cant overflow */ | 108 | /* back to multibyte; cant overflow */ |
96 | wcstombs(buf, wbuf21, INT_MAX); | 109 | wcstombs(buf, wbuf21, INT_MAX); |
97 | len = (len > 20) ? 0 : 20 - len; | 110 | len = (len > 20) ? 0 : 20 - len; |
98 | fprintf(stderr, "\r%s%*s%4d%% ", buf, len, "", ratio); | 111 | fprintf(stderr, "\r%s%*s%4u%% ", buf, len, "", ratio); |
99 | free(buf); | 112 | free(buf); |
100 | } | 113 | } |
101 | #else | 114 | #else |
102 | fprintf(stderr, "\r%-20.20s%4d%% ", curfile, ratio); | 115 | fprintf(stderr, "\r%-20.20s%4u%% ", curfile, ratio); |
103 | #endif | 116 | #endif |
104 | 117 | ||
105 | barlength = get_tty2_width() - 49; | 118 | barlength = get_tty2_width() - 49; |
106 | if (barlength > 0) { | 119 | if (barlength > 0) { |
107 | /* god bless gcc for variable arrays :) */ | 120 | /* god bless gcc for variable arrays :) */ |
108 | i = barlength * ratio / 100; | 121 | char buf[barlength + 1]; |
109 | { | 122 | unsigned stars = (unsigned)barlength * ratio / (unsigned)100; |
110 | char buf[i+1]; | 123 | memset(buf, ' ', barlength); |
111 | memset(buf, '*', i); | 124 | buf[barlength] = '\0'; |
112 | buf[i] = '\0'; | 125 | memset(buf, '*', stars); |
113 | fprintf(stderr, "|%s%*s|", buf, barlength - i, ""); | 126 | fprintf(stderr, "|%s|", buf); |
114 | } | ||
115 | } | 127 | } |
128 | |||
116 | i = 0; | 129 | i = 0; |
117 | abbrevsize = transferred + beg_range; | 130 | while (beg_and_transferred >= 100000) { |
118 | while (abbrevsize >= 100000) { | ||
119 | i++; | 131 | i++; |
120 | abbrevsize >>= 10; | 132 | beg_and_transferred >>= 10; |
121 | } | 133 | } |
122 | /* see http://en.wikipedia.org/wiki/Tera */ | 134 | /* see http://en.wikipedia.org/wiki/Tera */ |
123 | fprintf(stderr, "%6d%c ", (int)abbrevsize, " kMGTPEZY"[i]); | 135 | fprintf(stderr, "%6u%c ", (unsigned)beg_and_transferred, " kMGTPEZY"[i]); |
136 | #define beg_and_transferred dont_use_beg_and_transferred_below | ||
124 | 137 | ||
125 | elapsed = monotonic_sec(); | ||
126 | since_last_update = elapsed - p->lastupdate_sec; | ||
127 | if (transferred > p->lastsize) { | 138 | if (transferred > p->lastsize) { |
128 | p->lastupdate_sec = elapsed; | 139 | p->lastupdate_sec = elapsed; |
129 | p->lastsize = transferred; | 140 | p->lastsize = transferred; |
@@ -144,10 +155,10 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
144 | fprintf(stderr, "--:--:-- ETA"); | 155 | fprintf(stderr, "--:--:-- ETA"); |
145 | } else { | 156 | } else { |
146 | /* to_download / (transferred/elapsed) - elapsed: */ | 157 | /* to_download / (transferred/elapsed) - elapsed: */ |
147 | int eta = (int) ((unsigned long long)to_download*elapsed/transferred - elapsed); | ||
148 | /* (long long helps to have working ETA even if !LFS) */ | 158 | /* (long long helps to have working ETA even if !LFS) */ |
149 | i = eta % 3600; | 159 | unsigned eta = (unsigned long long)to_download*elapsed/(uoff_t)transferred - elapsed; |
150 | fprintf(stderr, "%02d:%02d:%02d ETA", eta / 3600, i / 60, i % 60); | 160 | unsigned secs = eta % 3600; |
161 | fprintf(stderr, "%02u:%02u:%02u ETA", eta / 3600, secs / 60, secs % 60); | ||
151 | } | 162 | } |
152 | } | 163 | } |
153 | } | 164 | } |