Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 18151
Collapse All | Expand All

(-)src/copy.c (+194 lines)
Lines 17-22 Link Here
17
17
18
/* Extracted from cp.c and librarified by Jim Meyering.  */
18
/* Extracted from cp.c and librarified by Jim Meyering.  */
19
19
20
/* Progress bar support added by Miika Pekkarinen. miipekk@ihme.org */
21
20
#include <config.h>
22
#include <config.h>
21
#include <stdio.h>
23
#include <stdio.h>
22
#include <assert.h>
24
#include <assert.h>
Lines 26-31 Link Here
26
# include <hurd.h>
28
# include <hurd.h>
27
#endif
29
#endif
28
30
31
#ifdef GWINSZ_IN_SYS_IOCTL
32
# include <sys/ioctl.h>
33
#endif
34
29
#include "system.h"
35
#include "system.h"
30
#include "error.h"
36
#include "error.h"
31
#include "backupfile.h"
37
#include "backupfile.h"
Lines 42-47 Link Here
42
#include "same.h"
48
#include "same.h"
43
#include "utimens.h"
49
#include "utimens.h"
44
#include "xreadlink.h"
50
#include "xreadlink.h"
51
#include "xstrtol.h"
45
#include "acl.h"
52
#include "acl.h"
46
53
47
#ifdef USE_XATTR
54
#ifdef USE_XATTR
Lines 77-82 struct F_triple Link Here
77
/* Initial size of the above hash table.  */
84
/* Initial size of the above hash table.  */
78
#define DEST_INFO_INITIAL_CAPACITY 61
85
#define DEST_INFO_INITIAL_CAPACITY 61
79
86
87
/* How many samples to take while calculating average speed */
88
#define SAMPLE_MAX 10
89
80
int euidaccess ();
90
int euidaccess ();
81
int yesno ();
91
int yesno ();
82
92
Lines 189-194 copy_dir (const char *src_path_in, const Link Here
189
  return -ret;
199
  return -ret;
190
}
200
}
191
201
202
/* Shorten a string '/long path/long file' to 'long fi...'
203
   Also adds padding bytes to end of the string if necessary */
204
char *shorten_path(const char *str, int max_width)
205
{
206
  char *shortname;
207
  char *filename = (char *) (rindex(str, '/'));
208
  int len;
209
  
210
  if (filename == NULL)
211
    {
212
      filename = (char *) str;
213
    }
214
  else
215
    {
216
      filename = (char *) &filename[1];
217
    }
218
219
  len = strlen(filename);
220
  shortname = (char *) xmalloc (max_width + 1);
221
  strncpy (shortname, filename, max_width);
222
  shortname[max_width] = '\0';
223
  if (len > max_width)
224
    {
225
      memset(&shortname[max_width - 3], '.', 3);
226
    }
227
  else
228
    {
229
      memset(&shortname[len], ' ', max_width - len);
230
    }
231
232
  return shortname;
233
}
234
235
char *si_units(off_t size)
236
{
237
  const static int buf_size = 20;
238
  char *buf;
239
  static char *unit_array[] = { "B", "KiB", "MiB", "GiB", "" };
240
  int i;
241
  
242
  buf = xmalloc(20);
243
  for (i = 0; size > 10000; i++)
244
    {
245
      if (unit_array[i][0] == '\0')
246
	{
247
	  i--;
248
	  break;
249
	}
250
      size /= 1024;
251
    }
252
253
  snprintf (buf, buf_size, "%lu %s", (unsigned long)size, unit_array[i]);
254
255
  return buf;
256
}
257
192
/* Copy a regular file from SRC_PATH to DST_PATH.
258
/* Copy a regular file from SRC_PATH to DST_PATH.
193
   If the source file contains holes, copies holes and blocks of zeros
259
   If the source file contains holes, copies holes and blocks of zeros
194
   in the source file as holes in the destination file.
260
   in the source file as holes in the destination file.
Lines 216-221 copy_reg (const char *src_path, const ch Link Here
216
  off_t n_read_total = 0;
282
  off_t n_read_total = 0;
217
  int last_write_made_hole = 0;
283
  int last_write_made_hole = 0;
218
  int make_holes = (x->sparse_mode == SPARSE_ALWAYS);
284
  int make_holes = (x->sparse_mode == SPARSE_ALWAYS);
285
  time_t t_start;
286
  time_t t_last;
287
  time_t t_now;
288
  int last_bytes = 0;
289
  int progress_bar_printed = 0;
290
  char *shortname = NULL;
291
  off_t sample_window[SAMPLE_MAX];
292
  off_t sample_sum = 0;
293
  int sample_count = 0;
294
  int line_length = 80;
295
#ifdef TIOCGWINSZ
296
  struct winsize ws;
297
#endif
219
298
220
  source_desc = open (src_path, O_RDONLY);
299
  source_desc = open (src_path, O_RDONLY);
221
  if (source_desc < 0)
300
  if (source_desc < 0)
Lines 313-318 copy_reg (const char *src_path, const ch Link Here
313
389
314
  buf = (char *) alloca (buf_size + sizeof (int));
390
  buf = (char *) alloca (buf_size + sizeof (int));
315
391
392
  time (&t_start);
393
  t_last = t_start;
394
316
  for (;;)
395
  for (;;)
317
    {
396
    {
318
      ssize_t n_read = read (source_desc, buf, buf_size);
397
      ssize_t n_read = read (source_desc, buf, buf_size);
Lines 377-382 copy_reg (const char *src_path, const ch Link Here
377
	    }
456
	    }
378
	  last_write_made_hole = 0;
457
	  last_write_made_hole = 0;
379
	}
458
	}
459
      
460
      time (&t_now);
461
      
462
      /* Progress bar stuff */
463
      if (! x->pbar_show || t_now - t_start < x->pbar_delay)
464
        {
465
	  continue;
466
	}
467
      
468
      if (! progress_bar_printed)
469
	{
470
          /* Column width check code copied from ls.c */
471
          char const *p = getenv ("COLUMNS");
472
          if (p && *p)
473
            {
474
	      long int tmp_long;
475
	      if (xstrtol (p, NULL, 0, &tmp_long, NULL) == LONGINT_OK
476
		  && 0 < tmp_long && tmp_long <= INT_MAX)
477
		{
478
		  line_length = (int) tmp_long;
479
		}
480
	      else
481
		{
482
		  error (0, 0,
483
			 _("ignoring invalid width in environment \
484
                      variable COLUMNS: %s"),
485
			 quotearg (p));
486
		}
487
            }
488
	  
489
#ifdef TIOCGWINSZ
490
	  if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0)
491
	    {
492
	      line_length = ws.ws_col;
493
	    }
494
#endif
495
	  if (line_length < 50)
496
	    {
497
	      continue;
498
	    }
499
500
	  /* Take a short filename for progress bar */
501
	  shortname = shorten_path(src_path, line_length - 48);
502
	  progress_bar_printed = 1;
503
        }
504
      
505
      if (t_now == t_last)
506
        {
507
          continue;
508
        }
509
      
510
      if (sample_count == SAMPLE_MAX)
511
        {
512
          int i;
513
	  
514
          sample_sum -= sample_window[0];
515
          for (i = 0; i < SAMPLE_MAX - 1; i++)
516
	    {
517
	      sample_window[i] = sample_window[i + 1];
518
	    }
519
	}
520
      else
521
	{
522
	  sample_count++;
523
	}
524
      
525
      {
526
	char *str_size;
527
	char *str_speed;
528
	char etabuf[64];
529
	time_t t_temp;
530
	      
531
        sample_window[sample_count - 1] = (n_read_total - last_bytes) /
532
                      (t_now - t_last);
533
        sample_sum += sample_window[sample_count - 1];
534
      
535
        /* Calculate the remaining time */
536
        t_temp = (src_open_sb.st_size - n_read_total) / (sample_sum / sample_count);
537
538
	/* Don't print the progress bar if the estimated remaining
539
	   time is low. */
540
	if (progress_bar_printed == 1 && t_temp < x->pbar_min_est)
541
	  {
542
	    continue;
543
	  }
544
	progress_bar_printed = 2;
545
546
	str_size = si_units(src_open_sb.st_size);
547
	str_speed = si_units(sample_sum / sample_count);
548
549
        strftime(etabuf, sizeof etabuf, "%H:%M.%S", 
550
                 gmtime(&t_temp));
551
        printf (_("%s | %3d%% | %9s | %9s/s | ETA %s\r"), shortname,
552
                (int)(n_read_total * 100 / src_open_sb.st_size),
553
                str_size, str_speed, etabuf);
554
        fflush (stdout);
555
	free(str_size);
556
	free(str_speed);
557
        t_last = t_now;
558
        last_bytes = n_read_total;
559
      }
560
    }
561
  
562
  /* Print a newline if progress bar is enabled and has been shown */
563
  if (progress_bar_printed == 2)
564
    {
565
      printf ("%s | 100%%\n", shortname);
380
    }
566
    }
381
567
382
  /* If the file ends with a `hole', something needs to be written at
568
  /* If the file ends with a `hole', something needs to be written at
Lines 411-416 close_src_desc: Link Here
411
    {
599
    {
412
      error (0, errno, _("closing %s"), quote (src_path));
600
      error (0, errno, _("closing %s"), quote (src_path));
413
      return_val = -1;
601
      return_val = -1;
602
    }
603
604
  if (shortname != NULL)
605
    {
606
      free (shortname);
414
    }
607
    }
415
608
416
  return return_val;
609
  return return_val;
(-)src/copy.h (+9 lines)
Lines 153-158 struct cp_options Link Here
153
  /* If nonzero, display the names of the files before copying them. */
153
  /* If nonzero, display the names of the files before copying them. */
154
  int verbose;
154
  int verbose;
155
155
156
  /* If nonzero, display a progress bar when following conditions are met:
157
     - pbar_delay defines how many seconds to wait before considering to display 
158
       the proggress bar.
159
     - pbar_min_est defines how many seconds estimated operation
160
       complete time should be at least to show the progress bar. */
161
  int pbar_show;
162
  int pbar_delay;
163
  int pbar_min_est;
164
  
156
  /* A pointer to either lstat or stat, depending on
165
  /* A pointer to either lstat or stat, depending on
157
     whether the copy should dereference symlinks.  */
166
     whether the copy should dereference symlinks.  */
158
  int (*xstat) ();
167
  int (*xstat) ();
(-)src/cp.c (-1 / +21 lines)
Lines 84-89 enum Link Here
84
/* Initial number of entries in the inode hash table.  */
84
/* Initial number of entries in the inode hash table.  */
85
#define INITIAL_ENTRY_TAB_SIZE 70
85
#define INITIAL_ENTRY_TAB_SIZE 70
86
86
87
/* Initial settings for progress bar when it's enabled.
88
   PROGRESS_DELAY defines how many seconds to wait before even
89
   considering to display a proggress bar.
90
   PROGRESS_MIN_EST defines how many seconds estimated operation
91
   complete time should be at least to show the progress bar. */
92
#define PROGRESS_DELAY    5
93
#define PROGRESS_MIN_EST  5
94
87
/* The invocation name of this program.  */
95
/* The invocation name of this program.  */
88
char *program_name;
96
char *program_name;
89
97
Lines 126-131 static struct option const long_opts[] = Link Here
126
  {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},
134
  {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},
127
  {"dereference", no_argument, NULL, 'L'},
135
  {"dereference", no_argument, NULL, 'L'},
128
  {"force", no_argument, NULL, 'f'},
136
  {"force", no_argument, NULL, 'f'},
137
  {"progress", no_argument, NULL, 'g'},
129
  {"interactive", no_argument, NULL, 'i'},
138
  {"interactive", no_argument, NULL, 'i'},
130
  {"link", no_argument, NULL, 'l'},
139
  {"link", no_argument, NULL, 'l'},
131
  {"no-dereference", no_argument, NULL, 'P'},
140
  {"no-dereference", no_argument, NULL, 'P'},
Lines 182-187 Mandatory arguments to long options are Link Here
182
      --no-dereference         never follow symbolic links\n\
191
      --no-dereference         never follow symbolic links\n\
183
  -f, --force                  if an existing destination file cannot be\n\
192
  -f, --force                  if an existing destination file cannot be\n\
184
                                 opened, remove it and try again\n\
193
                                 opened, remove it and try again\n\
194
  -g, --progress               show a progress bar if operation is going to\n\
195
                                 take a long time\n\
185
  -i, --interactive            prompt before overwrite\n\
196
  -i, --interactive            prompt before overwrite\n\
186
  -H                           follow command-line symbolic links\n\
197
  -H                           follow command-line symbolic links\n\
187
"), stdout);
198
"), stdout);
Lines 742-747 cp_option_init (struct cp_options *x) Link Here
742
753
743
  x->update = 0;
754
  x->update = 0;
744
  x->verbose = 0;
755
  x->verbose = 0;
756
	
757
  x->pbar_show = 0;
758
  x->pbar_delay = PROGRESS_DELAY;
759
  x->pbar_min_est = PROGRESS_MIN_EST;
760
	
745
  x->dest_info = NULL;
761
  x->dest_info = NULL;
746
  x->src_info = NULL;
762
  x->src_info = NULL;
747
}
763
}
Lines 846-852 main (int argc, char **argv) Link Here
846
     we'll actually use backup_suffix_string.  */
862
     we'll actually use backup_suffix_string.  */
847
  backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
863
  backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
848
864
849
  while ((c = getopt_long (argc, argv, "abdfHilLprsuvxPRS:V:", long_opts, NULL))
865
  while ((c = getopt_long (argc, argv, "abdfgHilLprsuvxPRS:V:", long_opts, NULL))
850
	 != -1)
866
	 != -1)
851
    {
867
    {
852
      switch (c)
868
      switch (c)
Lines 893-898 main (int argc, char **argv) Link Here
893
909
894
	case 'f':
910
	case 'f':
895
	  x.unlink_dest_after_failed_open = 1;
911
	  x.unlink_dest_after_failed_open = 1;
912
	  break;
913
		
914
	case 'g':
915
	  x.pbar_show = 1;
896
	  break;
916
	  break;
897
917
898
	case 'H':
918
	case 'H':
(-)src/mv.c (-1 / +22 lines)
Lines 45-50 Link Here
45
/* Initial number of entries in the inode hash table.  */
45
/* Initial number of entries in the inode hash table.  */
46
#define INITIAL_ENTRY_TAB_SIZE 70
46
#define INITIAL_ENTRY_TAB_SIZE 70
47
47
48
/* Initial settings for progress bar when it's enabled.
49
   PROGRESS_DELAY defines how many seconds to wait before even
50
   considering to display a proggress bar.
51
   PROGRESS_MIN_EST defines how many seconds estimated operation
52
   complete time should be at least to show the progress bar. */
53
#define PROGRESS_DELAY    5
54
#define PROGRESS_MIN_EST  5
55
48
/* For long options that have no equivalent short option, use a
56
/* For long options that have no equivalent short option, use a
49
   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
57
   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
50
enum
58
enum
Lines 79-84 static struct option const long_options[ Link Here
79
{
87
{
80
  {"backup", optional_argument, NULL, 'b'},
88
  {"backup", optional_argument, NULL, 'b'},
81
  {"force", no_argument, NULL, 'f'},
89
  {"force", no_argument, NULL, 'f'},
90
  {"progress", no_argument, NULL, 'g'},
82
  {"interactive", no_argument, NULL, 'i'},
91
  {"interactive", no_argument, NULL, 'i'},
83
  {"reply", required_argument, NULL, REPLY_OPTION},
92
  {"reply", required_argument, NULL, REPLY_OPTION},
84
  {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION},
93
  {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION},
Lines 141-146 cp_option_init (struct cp_options *x) Link Here
141
150
142
  x->update = 0;
151
  x->update = 0;
143
  x->verbose = 0;
152
  x->verbose = 0;
153
  x->pbar_show = 0;
154
  x->pbar_delay = PROGRESS_DELAY;
155
  x->pbar_min_est = PROGRESS_MIN_EST;
156
144
  x->xstat = lstat;
157
  x->xstat = lstat;
145
  x->dest_info = NULL;
158
  x->dest_info = NULL;
146
  x->src_info = NULL;
159
  x->src_info = NULL;
Lines 322-327 Mandatory arguments to long options are Link Here
322
  -b                           like --backup but does not accept an argument\n\
335
  -b                           like --backup but does not accept an argument\n\
323
  -f, --force                  do not prompt before overwriting\n\
336
  -f, --force                  do not prompt before overwriting\n\
324
                                 equivalent to --reply=yes\n\
337
                                 equivalent to --reply=yes\n\
338
  -g, --progress               show a progress bar if operation is going to\n\
339
                                 take a long time\n\
325
  -i, --interactive            prompt before overwrite\n\
340
  -i, --interactive            prompt before overwrite\n\
326
                                 equivalent to --reply=query\n\
341
                                 equivalent to --reply=query\n\
327
"), stdout);
342
"), stdout);
Lines 365-370 main (int argc, char **argv) Link Here
365
  int c;
380
  int c;
366
  int errors;
381
  int errors;
367
  int make_backups = 0;
382
  int make_backups = 0;
383
  int pbar_show = 0;
384
  int pbar_delay = PROGRESS_DELAY;
385
  int pbar_min_est = PROGRESS_MIN_EST;
368
  int dest_is_dir;
386
  int dest_is_dir;
369
  char *backup_suffix_string;
387
  char *backup_suffix_string;
370
  char *version_control_string = NULL;
388
  char *version_control_string = NULL;
Lines 390-396 main (int argc, char **argv) Link Here
390
408
391
  errors = 0;
409
  errors = 0;
392
410
393
  while ((c = getopt_long (argc, argv, "bfiuvS:V:", long_options, NULL)) != -1)
411
  while ((c = getopt_long (argc, argv, "bfgiuvS:V:", long_options, NULL)) != -1)
394
    {
412
    {
395
      switch (c)
413
      switch (c)
396
	{
414
	{
Lines 411-416 main (int argc, char **argv) Link Here
411
	  break;
429
	  break;
412
	case 'f':
430
	case 'f':
413
	  x.interactive = I_ALWAYS_YES;
431
	  x.interactive = I_ALWAYS_YES;
432
	  break;
433
	case 'g':
434
	  x.pbar_show = 1;
414
	  break;
435
	  break;
415
	case 'i':
436
	case 'i':
416
	  x.interactive = I_ASK_USER;
437
	  x.interactive = I_ASK_USER;

Return to bug 18151