lineedit: do not hang on error, but return error indicator.
[oweals/busybox.git] / libbb / progress.c
index 0e484da6c7d1d4ab1df62263128fa6c2dc4bd876..f53271398816b2d163bcdf1633aa1f9640411e51 100644 (file)
@@ -66,19 +66,32 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p,
                off_t transferred,
                off_t totalsize)
 {
-       off_t abbrevsize;
+       uoff_t beg_and_transferred;
        unsigned since_last_update, elapsed;
        unsigned ratio;
        int barlength, i;
 
+       /* totalsize == 0 if it is unknown */
+
+       elapsed = monotonic_sec();
+       since_last_update = elapsed - p->lastupdate_sec;
+       /* Do not update on every call
+        * (we can be called on every network read!) */
+       if (since_last_update == 0 && !totalsize)
+                       return;
+
+       beg_and_transferred = beg_range + transferred;
        ratio = 100;
-       if (totalsize) {
+       if (beg_and_transferred < totalsize) {
+               /* Do not update on every call
+                * (we can be called on every network read!) */
+               if (since_last_update == 0)
+                       return;
                /* long long helps to have it working even if !LFS */
-               ratio = (unsigned) (100ULL * (transferred+beg_range) / totalsize);
-               if (ratio > 100) ratio = 100;
+               ratio = 100ULL * beg_and_transferred / (uoff_t)totalsize;
        }
 
-#if ENABLE_FEATURE_ASSUME_UNICODE
+#if ENABLE_UNICODE_SUPPORT
        init_unicode();
        /* libbb candidate? */
        {
@@ -95,35 +108,33 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p,
                /* back to multibyte; cant overflow */
                wcstombs(buf, wbuf21, INT_MAX);
                len = (len > 20) ? 0 : 20 - len;
-               fprintf(stderr, "\r%s%*s%4d%% ", buf, len, "", ratio);
+               fprintf(stderr, "\r%s%*s%4u%% ", buf, len, "", ratio);
                free(buf);
        }
 #else
-       fprintf(stderr, "\r%-20.20s%4d%% ", curfile, ratio);
+       fprintf(stderr, "\r%-20.20s%4u%% ", curfile, ratio);
 #endif
 
        barlength = get_tty2_width() - 49;
        if (barlength > 0) {
                /* god bless gcc for variable arrays :) */
-               i = barlength * ratio / 100;
-               {
-                       char buf[i+1];
-                       memset(buf, '*', i);
-                       buf[i] = '\0';
-                       fprintf(stderr, "|%s%*s|", buf, barlength - i, "");
-               }
+               char buf[barlength + 1];
+               unsigned stars = (unsigned)barlength * ratio / (unsigned)100;
+               memset(buf, ' ', barlength);
+               buf[barlength] = '\0';
+               memset(buf, '*', stars);
+               fprintf(stderr, "|%s|", buf);
        }
+
        i = 0;
-       abbrevsize = transferred + beg_range;
-       while (abbrevsize >= 100000) {
+       while (beg_and_transferred >= 100000) {
                i++;
-               abbrevsize >>= 10;
+               beg_and_transferred >>= 10;
        }
        /* see http://en.wikipedia.org/wiki/Tera */
-       fprintf(stderr, "%6d%c ", (int)abbrevsize, " kMGTPEZY"[i]);
+       fprintf(stderr, "%6u%c ", (unsigned)beg_and_transferred, " kMGTPEZY"[i]);
+#define beg_and_transferred dont_use_beg_and_transferred_below
 
-       elapsed = monotonic_sec();
-       since_last_update = elapsed - p->lastupdate_sec;
        if (transferred > p->lastsize) {
                p->lastupdate_sec = elapsed;
                p->lastsize = transferred;
@@ -144,10 +155,10 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p,
                        fprintf(stderr, "--:--:-- ETA");
                } else {
                        /* to_download / (transferred/elapsed) - elapsed: */
-                       int eta = (int) ((unsigned long long)to_download*elapsed/transferred - elapsed);
                        /* (long long helps to have working ETA even if !LFS) */
-                       i = eta % 3600;
-                       fprintf(stderr, "%02d:%02d:%02d ETA", eta / 3600, i / 60, i % 60);
+                       unsigned eta = (unsigned long long)to_download*elapsed/(uoff_t)transferred - elapsed;
+                       unsigned secs = eta % 3600;
+                       fprintf(stderr, "%02u:%02u:%02u ETA", eta / 3600, secs / 60, secs % 60);
                }
        }
 }