-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi.

Here’s the patch refreshed against the latest coreutils 8.1.


Regards, Mathias

- --
debian/rules
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAksL2vYACgkQYfUFJ3ewsJj0wACeLK/CzGP4pu7RXxuEdtib3q3d
epQAn3ruREoL6Zv/jJfrD39JundZHlNR
=5VqH
-----END PGP SIGNATURE-----
#! /bin/sh /usr/share/dpatch/dpatch-run

@DPATCH@
--- coreutils-8.1/src/copy.c    2009-10-22 11:18:05.000000000 +0200
+++ coreutils-8.1/src/copy.c.new        2009-11-24 13:40:01.000000000 +0100
@@ -29,6 +29,10 @@
 # include <priv.h>
 #endif
 
+#ifdef GWINSZ_IN_SYS_IOCTL
+# include <sys/ioctl.h>
+#endif
+
 #include "system.h"
 #include "acl.h"
 #include "backupfile.h"
@@ -53,6 +57,9 @@
 #include "write-any-file.h"
 #include "areadlink.h"
 #include "yesno.h"
+#include "xstrtol.h"
+#include "human.h"
+#include "quotearg.h"
 
 #if USE_XATTR
 # include <attr/error_context.h>
@@ -102,6 +109,8 @@
 
 /* Initial size of the cp.dest_info hash table.  */
 #define DEST_INFO_INITIAL_CAPACITY 61
+ 
+#define SAMPLE_MAX 10
 
 static bool copy_internal (char const *src_name, char const *dst_name,
                            bool new_dst, dev_t device,
@@ -328,6 +337,31 @@
   free (name_space);
   return ok;
 }
+ 
+/* Shorten a string '/long path/long file' to 'long fi...'
+   Also adds padding bytes to end of the string if necessary */
+char *shorten_name(const char *str, size_t max_width)
+{
+  char *shortname;
+  const char *filename;
+  size_t len;
+
+  filename = base_name (str);
+  len = strlen(filename);
+  shortname = (char *) xmalloc (max_width + 1);
+  strncpy (shortname, filename, max_width);
+  shortname[max_width] = '\0';
+  if (len > max_width)
+    {
+      memset(shortname + max_width - 3, '.', 3);
+    }
+  else
+    {
+      memset(shortname + len, ' ', max_width - len);
+    }
+
+  return shortname;
+}
 
 /* Set the owner and owning group of DEST_DESC to the st_uid and
    st_gid fields of SRC_SB.  If DEST_DESC is undefined (-1), set
@@ -486,6 +520,19 @@
   struct stat src_open_sb;
   bool return_val = true;
   bool data_copy_required = true;
+  time_t t_start;
+  time_t t_last;
+  time_t t_now;
+  off_t last_bytes = 0;
+  int progress_bar_printed = 0;
+  char *shortname = NULL;
+  off_t sample_window[SAMPLE_MAX];
+  off_t sample_sum = 0;
+  int sample_count = 0;
+  long int line_length = 0;
+#ifdef TIOCGWINSZ
+  struct winsize ws;
+#endif
 
   source_desc = open (src_name,
                       (O_RDONLY | O_BINARY
@@ -705,6 +752,9 @@
       /* Make a buffer with space for a sentinel at the end.  */
       buf_alloc = xmalloc (buf_size + buf_alignment_slop);
       buf = ptr_align (buf_alloc, buf_alignment);
+ 
+      time (&t_start);
+      t_last = t_start;
 
       for (;;)
         {
@@ -787,8 +837,112 @@
                  file.  Unfortunately that doesn't work for certain files in
                  /proc with linux kernels from at least 2.6.9 .. 2.6.29.  */
             }
+
+          time (&t_now);
+
+          /* Progress bar stuff */
+          if (! x->pbar_show || t_now - t_start < x->pbar_delay)
+            {
+              continue;
+            }
+
+          if (! progress_bar_printed)
+            {
+              /* Column width check code copied from ls.c */
+              char const *p = getenv ("COLUMNS");
+              if (p && *p)
+                {
+                  long int tmp_long;
+                  if (xstrtol (p, NULL, 0, &tmp_long, NULL) == LONGINT_OK
+                      && 0 < tmp_long && tmp_long <= INT_MAX)
+                    {
+                      line_length = tmp_long;
+                    }
+                  else
+                    {
+                      error (0, 0,
+                       _("ignoring invalid width in environment \
+                       variable COLUMNS: %s"),
+                       quotearg (p));
+                    }
+                }
+
+#ifdef TIOCGWINSZ
+              if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 
0)
+                {
+                  line_length = ws.ws_col;
+                }
+#endif
+              if (line_length < 50)
+                {
+                  continue;
+                }
+
+              /* Take a short filename for progress bar */
+              shortname = shorten_name(src_name, line_length - 48);
+              progress_bar_printed = 1;
+            }
+
+          if (t_now == t_last)
+            {
+              continue;
+            }
+
+          if (sample_count == SAMPLE_MAX)
+            {
+              int i;
+
+              sample_sum -= sample_window[0];
+              for (i = 0; i < SAMPLE_MAX - 1; i++)
+                {
+                  sample_window[i] = sample_window[i + 1];
+                }
+            }
+          else
+            {
+              sample_count++;
+            }
+
+          {
+            char str_size[LONGEST_HUMAN_READABLE + 1];
+            char str_speed[LONGEST_HUMAN_READABLE + 1];
+            char etabuf[64];
+            time_t t_temp;
+
+            sample_window[sample_count - 1] = (n_read_total - last_bytes) /
+                                              (t_now - t_last);
+            sample_sum += sample_window[sample_count - 1];
+
+            /* Calculate the remaining time */
+            t_temp = (src_open_sb.st_size - n_read_total) / (sample_sum / 
sample_count);
+
+            /* Don't print the progress bar if the estimated remaining
+               time is low. */
+            if (progress_bar_printed == 1 && t_temp < x->pbar_min_est)
+              {
+                continue;
+              }
+            progress_bar_printed = 2;
+
+            strftime(etabuf, sizeof etabuf, "%H:%M.%S", 
+                     gmtime(&t_temp));
+            printf (_("%s | %3lu%% | %9s | %9s/s | ETA %s\r"), shortname,
+                    (unsigned long)(n_read_total * 100 / src_open_sb.st_size),
+                    human_readable(src_open_sb.st_size, str_size, 
human_autoscale|human_base_1024|human_space_before_unit|human_SI|human_B, 1, 1),
+                    human_readable(sample_sum / sample_count, str_speed, 
human_autoscale|human_base_1024|human_space_before_unit|human_SI|human_B, 1, 1),
+                    etabuf);
+            fflush (stdout);
+            t_last = t_now;
+            last_bytes = n_read_total;
+          }
         }
 
+        /* Print a newline if progress bar is enabled and has been shown */
+        if (progress_bar_printed == 2)
+          {
+            printf ("%s | 100%%\n", shortname);
+          }
+
       /* If the file ends with a `hole', we need to do something to record
          the length of the file.  On modern systems, calling ftruncate does
          the job.  On systems without native ftruncate support, we have to
@@ -807,6 +961,10 @@
             {
               error (0, errno, _("writing %s"), quote (dst_name));
               return_val = false;
+              if (shortname != NULL)
+                {
+                  free (shortname);
+                }
               goto close_src_and_dst_desc;
             }
         }
--- coreutils-8.1/src/copy.h    2009-11-24 13:40:42.000000000 +0100
+++ coreutils-8.1/src/copy.h.new        2009-11-24 13:40:54.000000000 +0100
@@ -229,6 +229,16 @@
   /* If true, display the names of the files before copying them. */
   bool verbose;
 
+  /* If true, display a progress bar when the following conditions are
+   * met:
+     - pbar_delay defines how many seconds to wait before considering to
+       display the progress bar
+     - pbar_min_est defines how many seconds estimated operation complete
+       time should be at least to show the progress bar. */
+  bool pbar_show;
+  int pbar_delay;
+  int pbar_min_est;
+
   /* If true, stdin is a tty.  */
   bool stdin_tty;
 
--- coreutils-8.1/src/cp.c      2009-09-29 15:27:54.000000000 +0200
+++ coreutils-8.1/src/cp.c.new  2009-11-24 13:45:07.000000000 +0100
@@ -82,6 +82,14 @@
   UNLINK_DEST_BEFORE_OPENING
 };
 
+/* Initial settings for progress bar when it's enabled.
+   PROGRESS_DELAY defines how many seconds to wait before even
+   considering to display a proggress bar.
+   PROGRESS_MIN_EST defines how many seconds estimated operation
+   complete time should be at least to show the progress bar. */
+#define PROGRESS_DELAY    5
+#define PROGRESS_MIN_EST  5
+
 /* True if the kernel is SELinux enabled.  */
 static bool selinux_enabled;
 
@@ -119,6 +127,7 @@
   {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},
   {"dereference", no_argument, NULL, 'L'},
   {"force", no_argument, NULL, 'f'},
+  {"progress", no_argument, NULL, 'g'},
   {"interactive", no_argument, NULL, 'i'},
   {"link", no_argument, NULL, 'l'},
   {"no-clobber", no_argument, NULL, 'n'},
@@ -176,6 +185,8 @@
   -f, --force                  if an existing destination file cannot be\n\
                                  opened, remove it and try again (redundant 
if\n\
                                  the -n option is used)\n\
+  -g, --progress               show a progress bar if operation is going to\n\
+                                 take a long time\n\
   -i, --interactive            prompt before overwrite (overrides a previous 
-n\n\
                                   option)\n\
   -H                           follow command-line symbolic links in SOURCE\n\
@@ -794,6 +805,10 @@
   x->update = false;
   x->verbose = false;
 
+  x->pbar_show = false;
+  x->pbar_delay = PROGRESS_DELAY;
+  x->pbar_min_est = PROGRESS_MIN_EST;
+
   /* By default, refuse to open a dangling destination symlink, because
      in general one cannot do that safely, give the current semantics of
      open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).
@@ -923,7 +938,7 @@
      we'll actually use backup_suffix_string.  */
   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
 
-  while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T",
+  while ((c = getopt_long (argc, argv, "abdfgHilLnprst:uvxPRS:T",
                            long_opts, NULL))
          != -1)
     {
@@ -999,6 +1014,10 @@
           x.dereference = DEREF_NEVER;
           break;
 
+        case 'g':
+          x.pbar_show = true;
+          break;
+
         case NO_PRESERVE_ATTRIBUTES_OPTION:
           decode_preserve_arg (optarg, &x, false);
           break;
--- coreutils-8.1/src/mv.c      2009-09-23 10:25:44.000000000 +0200
+++ coreutils-8.1/src/mv.c.new  2009-11-24 13:48:00.000000000 +0100
@@ -42,6 +42,14 @@
   proper_name ("David MacKenzie"), \
   proper_name ("Jim Meyering")
 
+/* Initial settings for progress bar when it's enabled.
+   PROGRESS_DELAY defines how many seconds to wait before even
+   considering to display a proggress bar.
+   PROGRESS_MIN_EST defines how many seconds estimated operation
+   complete time should be at least to show the progress bar. */
+#define PROGRESS_DELAY    5
+#define PROGRESS_MIN_EST  5
+
 /* For long options that have no equivalent short option, use a
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
@@ -56,6 +64,7 @@
 {
   {"backup", optional_argument, NULL, 'b'},
   {"force", no_argument, NULL, 'f'},
+  {"progress", no_argument, NULL, 'g'},
   {"interactive", no_argument, NULL, 'i'},
   {"no-clobber", no_argument, NULL, 'n'},
   {"no-target-directory", no_argument, NULL, 'T'},
@@ -83,6 +92,10 @@
 
   x->verbose = false;
 
+  x->pbar_show = false;
+  x->pbar_delay = PROGRESS_DELAY;
+  x->pbar_min_est = PROGRESS_MIN_EST;
+
   /* Since this program may well have to process additional command
      line arguments after any call to `rm', that function must preserve
      the initial working directory, in case one of those is a
@@ -135,6 +148,10 @@
   x->verbose = false;
   x->dest_info = NULL;
   x->src_info = NULL;
+
+  x->pbar_show = false;
+  x->pbar_delay = PROGRESS_DELAY;
+  x->pbar_min_est = PROGRESS_MIN_EST;
 }
 
 /* FILE is the last operand of this command.  Return true if FILE is a
@@ -298,6 +315,8 @@
       --backup[=CONTROL]       make a backup of each existing destination 
file\n\
   -b                           like --backup but does not accept an argument\n\
   -f, --force                  do not prompt before overwriting\n\
+  -g, --progress               show a progress bar if operation is going to\n\
+                                 take a long time\n\
   -i, --interactive            prompt before overwrite\n\
   -n, --no-clobber             do not overwrite an existing file\n\
 If you specify more than one of -i, -f, -n, only the final one takes effect.\n\
@@ -366,7 +385,7 @@
      we'll actually use backup_suffix_string.  */
   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
 
-  while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL))
+  while ((c = getopt_long (argc, argv, "bfgint:uvS:T", long_options, NULL))
          != -1)
     {
       switch (c)
@@ -379,6 +398,9 @@
         case 'f':
           x.interactive = I_ALWAYS_YES;
           break;
+        case 'g':
+          x.pbar_show = true;
+          break;
         case 'i':
           x.interactive = I_ASK_USER;
           break;
--- coreutils-8.1/src/remove.h  2009-09-21 14:29:33.000000000 +0200
+++ coreutils-8.1/src/remove.h.new      2009-11-24 13:48:37.000000000 +0100
@@ -59,6 +59,16 @@
   /* If true, display the name of each file removed.  */
   bool verbose;
 
+  /* If true, display a progress bar when the following conditions are
+   * met:
+     - pbar_delay defines how many seconds to wait before considering to
+       display the progress bar
+     - pbar_min_est defines how many seconds estimated operation complete
+       time should be at least to show the progress bar. */
+  bool pbar_show;
+  int pbar_delay;
+  int pbar_min_est;
+
   /* If true, treat the failure by the rm function to restore the
      current working directory as a fatal error.  I.e., if this field
      is true and the rm function cannot restore cwd, it must exit with

Attachment: 99_progressbar_8.1.sig
Description: Binary data

Reply via email to