Tidy up the reporting of the disk scan progress on standard error.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 30 Oct 2008 19:41:47 +0000 (19:41 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 30 Oct 2008 19:41:47 +0000 (19:41 +0000)
It's now conditional by default on stderr being a tty; it's
configurable on or off manually if necessary; and the terminal width
is obtained by TIOCGWINSZ instead of by guesswork.

git-svn-id: svn://svn.tartarus.org/sgt/agedu@8229 cda61777-01e9-0310-a592-d414129be87e

TODO
agedu.c

diff --git a/TODO b/TODO
index f08917b..6df0eb3 100644 (file)
--- a/TODO
+++ b/TODO
@@ -23,11 +23,6 @@ Before it's non-embarrassingly releasable:
     * reinstate filesystem crossing, though not doing so should
       remain the default
 
- - polish up disk-scan progress reporting
-    * by default it should be conditional on isatty(2)
-    * manual override to enable or disable
-    * we should find rather than guessing the terminal width
-
  - work out what to do about atimes on directories
     * one option is to read them during the scan and reinstate them
       after each recursion pop. Race-condition prone.
@@ -86,16 +81,23 @@ Future directions:
       results over the net to another machine where they'd be
       indexed; in particular, this way the indexing machine could be
       64-bit even if the machine owning the filesystems was only 32.
-    + ability to build a database _and_ immediately run one of the
-      ongoing interactive report modes (httpd, curses) would seem
-      handy.
+    + in the other direction, ability to build a database _and_
+      immediately run one of the ongoing interactive report modes
+      (httpd, curses) in a single invocation would seem handy.
 
  - portability
     + between Unices:
        * autoconf?
        * configure use of stat64
        * configure use of /proc/net/tcp
+       * configure use of /dev/random
+       * configure use of Linux syscall magic replacing readdir
        * what do we do elsewhere about _GNU_SOURCE?
-    + further afield: is there in fact any non-Unix OS that supports
-      atimes and hence can be used with agedu at all?
-       * yes! http://msdn.microsoft.com/en-us/library/ms724290.aspx
+    + http://msdn.microsoft.com/en-us/library/ms724290.aspx suggest
+      modern Windowses support atime-equivalents, so a Windows port
+      is possible in principle. Would need to modify the current
+      structure a lot, to abstract away (at least) memory-mapping of
+      files, details of disk scan procedure, networking for httpd,
+      the path separator character (yuck). Unclear what the right UI
+      would be on Windows, too; command-line exactly as now might be
+      considered just a _little_ unfriendly. Or perhaps not.
diff --git a/agedu.c b/agedu.c
index 242865e..c1955b4 100644 (file)
--- a/agedu.c
+++ b/agedu.c
@@ -15,6 +15,8 @@
 #include <sys/types.h>
 #include <fcntl.h>
 #include <sys/mman.h>
+#include <termios.h>
+#include <sys/ioctl.h>
 
 #include "du.h"
 #include "trie.h"
@@ -41,6 +43,7 @@ struct ctx {
     dev_t datafile_dev, filesystem_dev;
     ino_t datafile_ino;
     time_t last_output_update;
+    int progress, progwidth;
 };
 
 static int gotdata(void *vctx, const char *pathname, const struct stat64 *st)
@@ -73,8 +76,11 @@ static int gotdata(void *vctx, const char *pathname, const struct stat64 *st)
 
     t = time(NULL);
     if (t != ctx->last_output_update) {
-       fprintf(stderr, "%-79.79s\r", pathname);
-       fflush(stderr);
+       if (ctx->progress) {
+           fprintf(stderr, "%-*.*s\r", ctx->progwidth, ctx->progwidth,
+                   pathname);
+           fflush(stderr);
+       }
        ctx->last_output_update = t;
     }
 
@@ -141,6 +147,7 @@ int main(int argc, char **argv)
     enum { QUERY, HTML, SCAN, DUMP, HTTPD } mode = QUERY;
     char *minage = "0d";
     int auth = HTTPD_AUTH_MAGIC | HTTPD_AUTH_BASIC;
+    int progress = 1;
 
     while (--argc > 0) {
         char *p = *++argv;
@@ -172,6 +179,17 @@ int main(int argc, char **argv)
                } else if (!strcmp(p, "--httpd") ||
                           !strcmp(p, "--server")) {
                    mode = HTTPD;
+               } else if (!strcmp(p, "--progress") ||
+                          !strcmp(p, "--scan-progress")) {
+                   progress = 2;
+               } else if (!strcmp(p, "--no-progress") ||
+                          !strcmp(p, "--no-scan-progress")) {
+                   progress = 0;
+               } else if (!strcmp(p, "--tty-progress") ||
+                          !strcmp(p, "--tty-scan-progress") ||
+                          !strcmp(p, "--progress-tty") ||
+                          !strcmp(p, "--scan-progress-tty")) {
+                   progress = 1;
                } else if (!strcmp(p, "--file") ||
                           !strcmp(p, "--auth") ||
                           !strcmp(p, "--http-auth") ||
@@ -299,6 +317,18 @@ int main(int argc, char **argv)
 
        ctx->last_output_update = time(NULL);
 
+       /* progress==1 means report progress only if stderr is a tty */
+       if (progress == 1)
+           progress = isatty(2) ? 2 : 0;
+       ctx->progress = progress;
+       {
+           struct winsize ws;
+           if (progress && ioctl(2, TIOCGWINSZ, &ws) == 0)
+               ctx->progwidth = ws.ws_col - 1;
+           else
+               ctx->progwidth = 79;
+       }
+
        /*
         * Scan the directory tree, and write out the trie component
         * of the data file.
@@ -308,8 +338,10 @@ int main(int argc, char **argv)
        count = triebuild_finish(ctx->tb);
        triebuild_free(ctx->tb);
 
-       fprintf(stderr, "%-79s\r", "");
-       fflush(stderr);
+       if (ctx->progress) {
+           fprintf(stderr, "%-*s\r", ctx->progwidth, "");
+           fflush(stderr);
+       }
 
        /*
         * Work out how much space the cumulative index trees will