]> Dogcows Code - chaz/tar/blobdiff - src/checkpoint.c
Fix README
[chaz/tar] / src / checkpoint.c
index 3c3ca78d909ecfdc498e6e58e1424a77ea3a0c7b..54e7b5967de2bd77233eaa920f1d4f8cacd86738 100644 (file)
@@ -1,6 +1,6 @@
 /* Checkpoint management for tar.
 
-   Copyright 2007, 2013 Free Software Foundation, Inc.
+   Copyright 2007, 2013-2014 Free Software Foundation, Inc.
 
    This file is part of GNU tar.
 
@@ -21,6 +21,7 @@
 #include "common.h"
 #include "wordsplit.h"
 #include <sys/ioctl.h>
+#include <termios.h>
 #include "fprintftime.h"
 
 enum checkpoint_opcode
@@ -140,21 +141,26 @@ static const char *checkpoint_total_format[] = {
   "D"
 };
 
-static int
+static long
 getwidth (FILE *fp)
 {
+  char const *columns;
+
+#ifdef TIOCGWINSZ
   struct winsize ws;
+  if (ioctl (fileno (fp), TIOCGWINSZ, &ws) == 0 && 0 < ws.ws_col)
+    return ws.ws_col;
+#endif
 
-  ws.ws_col = ws.ws_row = 0;
-  if ((ioctl (fileno (fp), TIOCGWINSZ, (char *) &ws) < 0) || ws.ws_col == 0)
+  columns = getenv ("COLUMNS");
+  if (columns)
     {
-      const char *col = getenv ("COLUMNS");
-      if (col)
-       return strtol (col, NULL, 10);
-      else
-       return 80;
+      long int col = strtol (columns, NULL, 10);
+      if (0 < col)
+       return col;
     }
-  return ws.ws_col;
+
+  return 80;
 }
 
 static char *
@@ -185,7 +191,8 @@ getarg (const char *input, const char ** endp, char **argbuf, size_t *arglen)
 
 static int tty_cleanup;
 
-static const char *def_format = "%s: %t: %T%*\r";
+static const char *def_format =
+  "%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r";
 
 static int
 format_checkpoint_string (FILE *fp, size_t len,
@@ -200,7 +207,7 @@ format_checkpoint_string (FILE *fp, size_t len,
   static char *argbuf = NULL;
   static size_t arglen = 0;
   char *arg = NULL;
-  
+
   if (!input)
     {
       if (do_write)
@@ -216,7 +223,7 @@ format_checkpoint_string (FILE *fp, size_t len,
         *not* "Leyendo un punto de comprobaci@'on" */
        input = gettext ("Read checkpoint %u");
     }
-  
+
   for (ip = input; *ip; ip++)
     {
       if (*ip == '%')
@@ -238,7 +245,7 @@ format_checkpoint_string (FILE *fp, size_t len,
              len += format_checkpoint_string (fp, len, def_format, do_write,
                                               cpn);
              break;
-             
+
            case 'u':
              fputs (cps, fp);
              len += strlen (cps);
@@ -252,10 +259,35 @@ format_checkpoint_string (FILE *fp, size_t len,
            case 'd':
              len += fprintf (fp, "%.0f", compute_duration ());
              break;
-             
+
            case 'T':
-             compute_duration ();
-             len += format_total_stats (fp, checkpoint_total_format, ',', 0);
+             {
+               const char **fmt = checkpoint_total_format, *fmtbuf[3];
+               struct wordsplit ws;
+               compute_duration ();
+
+               if (arg)
+                 {
+                   ws.ws_delim = ",";
+                   if (wordsplit (arg, &ws, WRDSF_NOVAR | WRDSF_NOCMD |
+                                          WRDSF_QUOTE | WRDSF_DELIM))
+                     ERROR ((0, 0, _("cannot split string '%s': %s"),
+                             arg, wordsplit_strerror (&ws)));
+                   else
+                     {
+                       int i;
+
+                       for (i = 0; i < ws.ws_wordc; i++)
+                         fmtbuf[i] = ws.ws_wordv[i];
+                       for (; i < 3; i++)
+                         fmtbuf[i] = NULL;
+                       fmt = fmtbuf;
+                     }
+                 }
+               len += format_total_stats (fp, fmt, ',', 0);
+               if (arg)
+                 wordsplit_free (&ws);
+             }
              break;
 
            case 't':
@@ -269,15 +301,15 @@ format_checkpoint_string (FILE *fp, size_t len,
                len += fprintftime (fp, fmt, tm, 0, tv.tv_usec * 1000);
              }
              break;
-             
+
            case '*':
              {
-               int w = arg ? strtoul (arg, NULL, 10) : getwidth (fp);
+               long w = arg ? strtol (arg, NULL, 10) : getwidth (fp);
                for (; w > len; len++)
                  fputc (' ', fp);
              }
              break;
-             
+
            default:
              fputc ('%', fp);
              fputc (*ip, fp);
@@ -362,8 +394,8 @@ run_checkpoint_actions (bool do_write)
     }
 }
 
-static void
-finish_checkpoint_actions (void)
+void
+checkpoint_flush_actions (void)
 {
   struct checkpoint_action *p;
 
@@ -374,18 +406,17 @@ finish_checkpoint_actions (void)
        case cop_ttyout:
          if (tty && tty_cleanup)
            {
-             int w = getwidth (tty);
+             long w = getwidth (tty);
              while (w--)
                fputc (' ', tty);
              fputc ('\r', tty);
+             fflush (tty);
            }
          break;
        default:
          /* nothing */;
        }
     }
-  if (tty)
-    fclose (tty);
 }
 
 void
@@ -399,5 +430,9 @@ void
 checkpoint_finish (void)
 {
   if (checkpoint_option)
-    finish_checkpoint_actions ();
+    {
+      checkpoint_flush_actions ();
+      if (tty)
+       fclose (tty);
+    }
 }
This page took 0.024276 seconds and 4 git commands to generate.