-
-static void
-updateprogressmeter(int ignore)
-{
- int save_errno = errno;
-
- progressmeter(0);
- signal(SIGALRM, updateprogressmeter);
- alarm(PROGRESSTIME);
- errno = save_errno;
-}
-
-static int
-foregroundproc(void)
-{
- static pid_t pgrp = -1;
- int ctty_pgrp;
-
- if (pgrp == -1)
- pgrp = getpgrp();
-
-#ifdef HAVE_TCGETPGRP
- return ((ctty_pgrp = tcgetpgrp(STDOUT_FILENO)) != -1 &&
- ctty_pgrp == pgrp);
-#else
- return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 &&
- ctty_pgrp == pgrp));
-#endif
-}
-
-void
-progressmeter(int flag)
-{
- static const char spaces[] = " "
- " "
- " "
- " "
- " "
- " ";
- static const char prefixes[] = " KMGTP";
- static struct timeval lastupdate;
- static off_t lastsize;
- struct timeval now, td, wait;
- off_t cursize, abbrevsize, bytespersec;
- double elapsed;
- int ratio, remaining, i, ai, bi, nspaces;
- char buf[512];
-
- if (flag == -1) {
- (void) gettimeofday(&start, (struct timezone *) 0);
- lastupdate = start;
- lastsize = 0;
- }
- if (foregroundproc() == 0)
- return;
-
- (void) gettimeofday(&now, (struct timezone *) 0);
- cursize = statbytes;
- if (totalbytes != 0) {
- ratio = 100.0 * cursize / totalbytes;
- ratio = MAX(ratio, 0);
- ratio = MIN(ratio, 100);
- } else
- ratio = 100;
-
- abbrevsize = cursize;
- for (ai = 0; abbrevsize >= 10000 && ai < sizeof(prefixes); ai++)
- abbrevsize >>= 10;
-
- timersub(&now, &lastupdate, &wait);
- if (cursize > lastsize) {
- lastupdate = now;
- lastsize = cursize;
- wait.tv_sec = 0;
- }
- timersub(&now, &start, &td);
- elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
-
- bytespersec = 0;
- if (statbytes > 0) {
- bytespersec = statbytes;
- if (elapsed > 0.0)
- bytespersec /= elapsed;
- }
- for (bi = 1; bytespersec >= 1024000 && bi < sizeof(prefixes); bi++)
- bytespersec >>= 10;
-
- nspaces = MIN(getttywidth() - 79, sizeof(spaces) - 1);
-
- snprintf(buf, sizeof(buf),
- "\r%-45.45s%.*s%3d%% %4lld%c%c %3lld.%01d%cB/s",
- curfile,
- nspaces,
- spaces,
- ratio,
- (long long)abbrevsize,
- prefixes[ai],
- ai == 0 ? ' ' : 'B',
- (long long)(bytespersec / 1024),
- (int)((bytespersec % 1024) * 10 / 1024),
- prefixes[bi]
- );
-
- if (flag != 1 &&
- (statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes)) {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- " --:-- ETA");
- } else if (wait.tv_sec >= STALLTIME) {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- " - stalled -");
- } else {
- if (flag != 1)
- remaining = (int)(totalbytes / (statbytes / elapsed) -
- elapsed);
- else
- remaining = elapsed;
-
- i = remaining / 3600;
- if (i)
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "%2d:", i);
- else
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- " ");
- i = remaining % 3600;
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "%02d:%02d%s", i / 60, i % 60,
- (flag != 1) ? " ETA" : " ");
- }
- atomicio(write, fileno(stdout), buf, strlen(buf));
-
- if (flag == -1) {
- mysignal(SIGALRM, updateprogressmeter);
- alarm(PROGRESSTIME);
- } else if (flag == 1) {
- alarm(0);
- atomicio(write, fileno(stdout), "\n", 1);
- statbytes = 0;
- }
-}
-
-int
-getttywidth(void)
-{
- struct winsize winsize;
-
- if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
- return (winsize.ws_col ? winsize.ws_col : 80);
- else
- return (80);
-}