Magellan Linux

Annotation of /trunk/coreutils/patches-5.3.0/coreutils-5.3.0-gen-progress-bar.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 44 - (hide annotations) (download)
Thu Oct 13 21:17:16 2005 UTC (18 years, 7 months ago) by niro
File size: 12049 byte(s)
patch set for coretutils-5.3.0

1 niro 44 Upstream has been contacted about this a few times ...
2    
3     they dont want progress bars in mv/cp:
4     http://lists.gnu.org/archive/html/bug-coreutils/2003-08/msg00114.html
5     http://lists.gnu.org/archive/html/bug-coreutils/2003-09/msg00083.html
6     http://lists.gnu.org/archive/html/bug-coreutils/2003-09/msg00084.html
7    
8     but they don't seem to mind a general util ... add this to future patchset:
9     http://lists.gnu.org/archive/html/bug-coreutils/2003-09/msg00101.html
10     http://lists.gnu.org/archive/html/bug-coreutils/2004-02/msg00071.html
11    
12     diff -urN 1/src/copy.c 2/src/copy.c
13     --- 1/src/copy.c 2004-09-20 08:27:12.000000000 +0100
14     +++ 2/src/copy.c 2005-03-26 15:53:57.000000000 +0000
15     @@ -17,6 +17,8 @@
16    
17     /* Extracted from cp.c and librarified by Jim Meyering. */
18    
19     +/* Progress bar support added by Miika Pekkarinen. miipekk@ihme.org */
20     +
21     #include <config.h>
22     #include <stdio.h>
23     #include <assert.h>
24     @@ -26,6 +28,10 @@
25     # include <hurd.h>
26     #endif
27    
28     +#ifdef GWINSZ_IN_SYS_IOCTL
29     +# include <sys/ioctl.h>
30     +#endif
31     +
32     #include "system.h"
33     #include "backupfile.h"
34     #include "copy.h"
35     @@ -44,3 +50,4 @@
36     #include "savedir.h"
37     #include "utimens.h"
38     +#include "xstrtol.h"
39     #include "xreadlink.h"
40     @@ -80,6 +87,8 @@
41     /* Initial size of the above hash table. */
42     #define DEST_INFO_INITIAL_CAPACITY 61
43    
44     +#define SAMPLE_MAX 10
45     +
46     static bool copy_internal (const char *src_path, const char *dst_path,
47     bool new_dst, dev_t device,
48     struct dir_list *ancestors,
49     @@ -186,6 +195,62 @@
50     return ok;
51     }
52    
53     +/* Shorten a string '/long path/long file' to 'long fi...'
54     + Also adds padding bytes to end of the string if necessary */
55     +char *shorten_path(const char *str, int max_width)
56     +{
57     + char *shortname;
58     + char *filename = (char *) (rindex(str, '/'));
59     + int len;
60     +
61     + if (filename == NULL)
62     + {
63     + filename = (char *) str;
64     + }
65     + else
66     + {
67     + filename = (char *) &filename[1];
68     + }
69     +
70     + len = strlen(filename);
71     + shortname = (char *) xmalloc (max_width + 1);
72     + strncpy (shortname, filename, max_width);
73     + shortname[max_width] = '\0';
74     + if (len > max_width)
75     + {
76     + memset(&shortname[max_width - 3], '.', 3);
77     + }
78     + else
79     + {
80     + memset(&shortname[len], ' ', max_width - len);
81     + }
82     +
83     + return shortname;
84     +}
85     +
86     +char *si_units(off_t size)
87     +{
88     + const static int buf_size = 20;
89     + char *buf;
90     + static char *unit_array[] = { "B", "KiB", "MiB", "GiB", "" };
91     + int i;
92     +
93     + buf = xmalloc(20);
94     + for (i = 0; size > 10000; i++)
95     + {
96     + if (unit_array[i][0] == '\0')
97     + {
98     + i--;
99     + break;
100     + }
101     + size /= 1024;
102     + }
103     +
104     + snprintf (buf, buf_size, "%lu %s", (unsigned long)size, unit_array[i]);
105     +
106     + return buf;
107     +}
108     +
109     /* Copy a regular file from SRC_PATH to DST_PATH.
110     If the source file contains holes, copies holes and blocks of zeros
111     in the source file as holes in the destination file.
112     @@ -214,6 +279,19 @@
113     off_t n_read_total = 0;
114     bool last_write_made_hole = false;
115     bool make_holes = false;
116     + time_t t_start;
117     + time_t t_last;
118     + time_t t_now;
119     + int last_bytes = 0;
120     + int progress_bar_printed = 0;
121     + char *shortname = NULL;
122     + off_t sample_window[SAMPLE_MAX];
123     + off_t sample_sum = 0;
124     + int sample_count = 0;
125     + int line_length = 0;
126     +#ifdef TIOCGWINSZ
127     + struct winsize ws;
128     +#endif
129    
130     source_desc = open (src_path, O_RDONLY);
131     if (source_desc < 0)
132     @@ -318,6 +396,9 @@
133     buf = alloca (buf_size + sizeof (int) + buf_alignment - 1);
134     buf = ptr_align (buf, buf_alignment);
135    
136     + time (&t_start);
137     + t_last = t_start;
138     +
139     for (;;)
140     {
141     ssize_t n_read = read (source_desc, buf, buf_size);
142     @@ -382,6 +463,113 @@
143     }
144     last_write_made_hole = false;
145     }
146     +
147     + time (&t_now);
148     +
149     + /* Progress bar stuff */
150     + if (! x->pbar_show || t_now - t_start < x->pbar_delay)
151     + {
152     + continue;
153     + }
154     +
155     + if (! progress_bar_printed)
156     + {
157     + /* Column width check code copied from ls.c */
158     + char const *p = getenv ("COLUMNS");
159     + if (p && *p)
160     + {
161     + long int tmp_long;
162     + if (xstrtol (p, NULL, 0, &tmp_long, NULL) == LONGINT_OK
163     + && 0 < tmp_long && tmp_long <= INT_MAX)
164     + {
165     + line_length = (int) tmp_long;
166     + }
167     + else
168     + {
169     + error (0, 0,
170     + _("ignoring invalid width in environment \
171     + variable COLUMNS: %s"),
172     + quotearg (p));
173     + }
174     + }
175     +
176     +#ifdef TIOCGWINSZ
177     + if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0)
178     + {
179     + line_length = ws.ws_col;
180     + }
181     +#endif
182     + if (line_length < 50)
183     + {
184     + continue;
185     + }
186     +
187     + /* Take a short filename for progress bar */
188     + shortname = shorten_path(src_path, line_length - 48);
189     + progress_bar_printed = 1;
190     + }
191     +
192     + if (t_now == t_last)
193     + {
194     + continue;
195     + }
196     +
197     + if (sample_count == SAMPLE_MAX)
198     + {
199     + int i;
200     +
201     + sample_sum -= sample_window[0];
202     + for (i = 0; i < SAMPLE_MAX - 1; i++)
203     + {
204     + sample_window[i] = sample_window[i + 1];
205     + }
206     + }
207     + else
208     + {
209     + sample_count++;
210     + }
211     +
212     + {
213     + char *str_size;
214     + char *str_speed;
215     + char etabuf[64];
216     + time_t t_temp;
217     +
218     + sample_window[sample_count - 1] = (n_read_total - last_bytes) /
219     + (t_now - t_last);
220     + sample_sum += sample_window[sample_count - 1];
221     +
222     + /* Calculate the remaining time */
223     + t_temp = (src_open_sb.st_size - n_read_total) / (sample_sum / sample_count);
224     +
225     + /* Don't print the progress bar if the estimated remaining
226     + time is low. */
227     + if (progress_bar_printed == 1 && t_temp < x->pbar_min_est)
228     + {
229     + continue;
230     + }
231     + progress_bar_printed = 2;
232     +
233     + str_size = si_units(src_open_sb.st_size);
234     + str_speed = si_units(sample_sum / sample_count);
235     +
236     + strftime(etabuf, sizeof etabuf, "%H:%M.%S",
237     + gmtime(&t_temp));
238     + printf (_("%s | %3d%% | %9s | %9s/s | ETA %s\r"), shortname,
239     + (int)(n_read_total * 100 / src_open_sb.st_size),
240     + str_size, str_speed, etabuf);
241     + fflush (stdout);
242     + free(str_size);
243     + free(str_speed);
244     + t_last = t_now;
245     + last_bytes = n_read_total;
246     + }
247     + }
248     +
249     + /* Print a newline if progress bar is enabled and has been shown */
250     + if (progress_bar_printed == 2)
251     + {
252     + printf ("%s | 100%%\n", shortname);
253     }
254    
255     /* If the file ends with a `hole', something needs to be written at
256     @@ -418,6 +606,11 @@
257     return_val = false;
258     }
259    
260     + if (shortname != NULL)
261     + {
262     + free (shortname);
263     + }
264     +
265     return return_val;
266     }
267    
268     diff -urN 1/src/copy.h 2/src/copy.h
269     --- 1/src/copy.h 2004-11-26 09:03:45.000000000 +0000
270     +++ 2/src/copy.h 2005-03-26 15:44:50.000000000 +0000
271     @@ -154,6 +154,16 @@
272     /* If true, display the names of the files before copying them. */
273     bool verbose;
274    
275     + /* If true, display a progress bar when the following conditions are
276     + * met:
277     + - pbar_delay defines how many seconds to wait before considering to
278     + display the progress bar
279     + - pbar_min_est defines how many seconds estimated operation complete
280     + time should be at least to show the progress bar. */
281     + bool pbar_show;
282     + int pbar_delay;
283     + int pbar_min_est;
284     +
285     /* If true, stdin is a tty. */
286     bool stdin_tty;
287    
288     diff -urN 1/src/cp.c 2/src/cp.c
289     --- 1/src/cp.c 2004-10-10 20:10:09.000000000 +0100
290     +++ 2/src/cp.c 2005-03-26 15:46:00.000000000 +0000
291     @@ -84,6 +84,14 @@
292     /* Initial number of entries in the inode hash table. */
293     #define INITIAL_ENTRY_TAB_SIZE 70
294    
295     +/* Initial settings for progress bar when it's enabled.
296     + PROGRESS_DELAY defines how many seconds to wait before even
297     + considering to display a proggress bar.
298     + PROGRESS_MIN_EST defines how many seconds estimated operation
299     + complete time should be at least to show the progress bar. */
300     +#define PROGRESS_DELAY 5
301     +#define PROGRESS_MIN_EST 5
302     +
303     /* The invocation name of this program. */
304     char *program_name;
305    
306     @@ -123,6 +131,7 @@
307     {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},
308     {"dereference", no_argument, NULL, 'L'},
309     {"force", no_argument, NULL, 'f'},
310     + {"progress", no_argument, NULL, 'g'},
311     {"interactive", no_argument, NULL, 'i'},
312     {"link", no_argument, NULL, 'l'},
313     {"no-dereference", no_argument, NULL, 'P'},
314     @@ -180,6 +189,8 @@
315     --no-dereference never follow symbolic links\n\
316     -f, --force if an existing destination file cannot be\n\
317     opened, remove it and try again\n\
318     + -g, --progress show a progress bar if operation is going to\n\
319     + take a long time\n\
320     -i, --interactive prompt before overwrite\n\
321     -H follow command-line symbolic links\n\
322     "), stdout);
323     @@ -711,6 +722,11 @@
324    
325     x->update = false;
326     x->verbose = false;
327     +
328     + x->pbar_show = false;
329     + x->pbar_delay = PROGRESS_DELAY;
330     + x->pbar_min_est = PROGRESS_MIN_EST;
331     +
332     x->dest_info = NULL;
333     x->src_info = NULL;
334     }
335     @@ -817,7 +833,7 @@
336     we'll actually use backup_suffix_string. */
337     backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
338    
339     - while ((c = getopt_long (argc, argv, "abdfHilLprst:uvxPRS:TV:",
340     + while ((c = getopt_long (argc, argv, "abdfgHilLprst:uvxPRS:TV:",
341     long_opts, NULL))
342     != -1)
343     {
344     @@ -887,6 +903,10 @@
345     case NO_PRESERVE_ATTRIBUTES_OPTION:
346     decode_preserve_arg (optarg, &x, false);
347     break;
348     +
349     + case 'g':
350     + x.pbar_show = 1;
351     + break;
352    
353     case PRESERVE_ATTRIBUTES_OPTION:
354     if (optarg == NULL)
355     diff -urN 1/src/mv.c 2/src/mv.c
356     --- 1/src/mv.c 2004-09-22 13:41:20.000000000 +0100
357     +++ 2/src/mv.c 2005-03-26 15:48:35.000000000 +0000
358     @@ -45,6 +45,14 @@
359     /* Initial number of entries in the inode hash table. */
360     #define INITIAL_ENTRY_TAB_SIZE 70
361    
362     +/* Initial settings for progress bar when it's enabled.
363     + PROGRESS_DELAY defines how many seconds to wait before even
364     + considering to display a proggress bar.
365     + PROGRESS_MIN_EST defines how many seconds estimated operation
366     + complete time should be at least to show the progress bar. */
367     +#define PROGRESS_DELAY 5
368     +#define PROGRESS_MIN_EST 5
369     +
370     /* For long options that have no equivalent short option, use a
371     non-character as a pseudo short option, starting with CHAR_MAX + 1. */
372     enum
373     @@ -75,6 +83,7 @@
374     {
375     {"backup", optional_argument, NULL, 'b'},
376     {"force", no_argument, NULL, 'f'},
377     + {"progress", no_argument, NULL, 'g'},
378     {"interactive", no_argument, NULL, 'i'},
379     {"no-target-directory", no_argument, NULL, 'T'},
380     {"reply", required_argument, NULL, REPLY_OPTION},
381     @@ -143,6 +152,10 @@
382    
383     x->update = false;
384     x->verbose = false;
385     + x->pbar_show = false;
386     + x->pbar_delay = PROGRESS_DELAY;
387     + x->pbar_min_est = PROGRESS_MIN_EST;
388     +
389     x->dest_info = NULL;
390     x->src_info = NULL;
391     }
392     @@ -313,6 +326,8 @@
393     -b like --backup but does not accept an argument\n\
394     -f, --force do not prompt before overwriting\n\
395     (equivalent to --reply=yes)\n\
396     + -g, --progress show a progress bar if operation is going to\n\
397     + take a long time\n\
398     -i, --interactive prompt before overwrite\n\
399     (equivalent to --reply=query)\n\
400     "), stdout);
401     @@ -357,6 +372,9 @@
402     int c;
403     bool ok;
404     bool make_backups = false;
405     + bool pbar_show = false;
406     + int pbar_delay = PROGRESS_DELAY;
407     + int pbar_min_est = PROGRESS_MIN_EST;
408     char *backup_suffix_string;
409     char *version_control_string = NULL;
410     struct cp_options x;
411     @@ -379,7 +397,7 @@
412     we'll actually use backup_suffix_string. */
413     backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
414    
415     - while ((c = getopt_long (argc, argv, "bfit:uvS:TV:", long_options, NULL))
416     + while ((c = getopt_long (argc, argv, "bfgit:uvS:TV:", long_options, NULL))
417     != -1)
418     {
419     switch (c)
420     @@ -399,6 +417,9 @@
421     case 'f':
422     x.interactive = I_ALWAYS_YES;
423     break;
424     + case 'g':
425     + x.pbar_show = 1;
426     + break;
427     case 'i':
428     x.interactive = I_ASK_USER;
429     break;