Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/coreutils/dd.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 8  Line 8 
8   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
9   */   */
10    
 #include <signal.h>  /* For FEATURE_DD_SIGNAL_HANDLING */  
11  #include "libbb.h"  #include "libbb.h"
12    
13  /* This is a NOEXEC applet. Be very careful! */  /* This is a NOEXEC applet. Be very careful! */
# Line 30  static const struct suffix_mult dd_suffi Line 29  static const struct suffix_mult dd_suffi
29   { "M", 1048576 },   { "M", 1048576 },
30   { "GD", 1000000000 },   { "GD", 1000000000 },
31   { "G", 1073741824 },   { "G", 1073741824 },
32   { }   { "", 0 }
33  };  };
34    
35  struct globals {  struct globals {
36   off_t out_full, out_part, in_full, in_part;   off_t out_full, out_part, in_full, in_part;
37    #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
38     unsigned long long total_bytes;
39     unsigned long long begin_time_us;
40    #endif
41  };  };
42  #define G (*(struct globals*)&bb_common_bufsiz1)  #define G (*(struct globals*)&bb_common_bufsiz1)
43  /* We have to zero it out because of NOEXEC */  #define INIT_G() do { \
44  #define INIT_G() memset(&G, 0, sizeof(G))   /* we have to zero it out because of NOEXEC */ \
45     memset(&G, 0, sizeof(G)); \
46    } while (0)
47    
48    
49  static void dd_output_status(int UNUSED_PARAM cur_signal)  static void dd_output_status(int UNUSED_PARAM cur_signal)
50  {  {
51    #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
52     double seconds;
53     unsigned long long bytes_sec;
54     unsigned long long now_us = monotonic_us(); /* before fprintf */
55    #endif
56    
57   /* Deliberately using %u, not %d */   /* Deliberately using %u, not %d */
58   fprintf(stderr, "%"OFF_FMT"u+%"OFF_FMT"u records in\n"   fprintf(stderr, "%"OFF_FMT"u+%"OFF_FMT"u records in\n"
59   "%"OFF_FMT"u+%"OFF_FMT"u records out\n",   "%"OFF_FMT"u+%"OFF_FMT"u records out\n",
60   G.in_full, G.in_part,   G.in_full, G.in_part,
61   G.out_full, G.out_part);   G.out_full, G.out_part);
62    
63    #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
64     fprintf(stderr, "%llu bytes (%sB) copied, ",
65     G.total_bytes,
66     /* show fractional digit, use suffixes */
67     make_human_readable_str(G.total_bytes, 1, 0)
68     );
69     /* Corner cases:
70     * ./busybox dd </dev/null >/dev/null
71     * ./busybox dd bs=1M count=2000 </dev/zero >/dev/null
72     * (echo DONE) | ./busybox dd >/dev/null
73     * (sleep 1; echo DONE) | ./busybox dd >/dev/null
74     */
75     seconds = (now_us - G.begin_time_us) / 1000000.0;
76     bytes_sec = G.total_bytes / seconds;
77     fprintf(stderr, "%f seconds, %sB/s\n",
78     seconds,
79     /* show fractional digit, use suffixes */
80     make_human_readable_str(bytes_sec, 1, 0)
81     );
82    #endif
83  }  }
84    
85  static ssize_t full_write_or_warn(const void *buf, size_t len,  static ssize_t full_write_or_warn(const void *buf, size_t len,
# Line 69  static bool write_and_stats(const void * Line 101  static bool write_and_stats(const void *
101   G.out_full++;   G.out_full++;
102   else if (n) /* > 0 */   else if (n) /* > 0 */
103   G.out_part++;   G.out_part++;
104    #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
105     G.total_bytes += n;
106    #endif
107   return 0;   return 0;
108  }  }
109    
110  #if ENABLE_LFS  #if ENABLE_LFS
111  #define XATOU_SFX xatoull_sfx  # define XATOU_SFX xatoull_sfx
112  #else  #else
113  #define XATOU_SFX xatoul_sfx  # define XATOU_SFX xatoul_sfx
114  #endif  #endif
115    
116  int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
# Line 154  int dd_main(int argc UNUSED_PARAM, char Line 189  int dd_main(int argc UNUSED_PARAM, char
189    
190   memset(&Z, 0, sizeof(Z));   memset(&Z, 0, sizeof(Z));
191   INIT_G();   INIT_G();
192   //fflush(NULL); - is this needed because of NOEXEC?   //fflush_all(); - is this needed because of NOEXEC?
   
 #if ENABLE_FEATURE_DD_SIGNAL_HANDLING  
  signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status);  
 #endif  
193    
194   for (n = 1; argv[n]; n++) {   for (n = 1; argv[n]; n++) {
195   int what;   int what;
# Line 245  int dd_main(int argc UNUSED_PARAM, char Line 276  int dd_main(int argc UNUSED_PARAM, char
276   flags |= FLAG_TWOBUFS;   flags |= FLAG_TWOBUFS;
277   obuf = xmalloc(obs);   obuf = xmalloc(obs);
278   }   }
279    
280    #if ENABLE_FEATURE_DD_SIGNAL_HANDLING
281     signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status);
282    #endif
283    #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
284     G.begin_time_us = monotonic_us();
285    #endif
286    
287   if (infile != NULL)   if (infile != NULL)
288   xmove_fd(xopen(infile, O_RDONLY), ifd);   xmove_fd(xopen(infile, O_RDONLY), ifd);
289   else {   else {
# Line 287  int dd_main(int argc UNUSED_PARAM, char Line 326  int dd_main(int argc UNUSED_PARAM, char
326   }   }
327    
328   while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) {   while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) {
  if (flags & FLAG_NOERROR) /* Pre-zero the buffer if conv=noerror */  
  memset(ibuf, 0, ibs);  
329   n = safe_read(ifd, ibuf, ibs);   n = safe_read(ifd, ibuf, ibs);
330   if (n == 0)   if (n == 0)
331   break;   break;
332   if (n < 0) {   if (n < 0) {
333     /* "Bad block" */
334   if (!(flags & FLAG_NOERROR))   if (!(flags & FLAG_NOERROR))
335   goto die_infile;   goto die_infile;
  n = ibs;  
336   bb_simple_perror_msg(infile);   bb_simple_perror_msg(infile);
337     /* GNU dd with conv=noerror skips over bad blocks */
338     xlseek(ifd, ibs, SEEK_CUR);
339     /* conv=noerror,sync writes NULs,
340     * conv=noerror just ignores input bad blocks */
341     n = 0;
342   }   }
343   if ((size_t)n == ibs)   if ((size_t)n == ibs)
344   G.in_full++;   G.in_full++;
345   else {   else {
346   G.in_part++;   G.in_part++;
347   if (flags & FLAG_SYNC) {   if (flags & FLAG_SYNC) {
348   memset(ibuf + n, '\0', ibs - n);   memset(ibuf + n, 0, ibs - n);
349   n = ibs;   n = ibs;
350   }   }
351   }   }

Legend:
Removed from v.983  
changed lines
  Added in v.984