aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorAri Sundholm <ari@tuxera.com>2015-02-07 01:41:22 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2015-02-07 01:41:22 +0100
commitf22a838aed8264f2f3a20ea9865d7d2e9ccb26c1 (patch)
treecbeb6470f501536461bb0dbb7da6b943fcc0627c /coreutils
parent7e66102f762a7d80715f0c7e5925433256b78cee (diff)
downloadbusybox-w32-f22a838aed8264f2f3a20ea9865d7d2e9ccb26c1.tar.gz
busybox-w32-f22a838aed8264f2f3a20ea9865d7d2e9ccb26c1.tar.bz2
busybox-w32-f22a838aed8264f2f3a20ea9865d7d2e9ccb26c1.zip
dd: add optional support for status=noxfer/none
While at it, added 'B' number suffixes, upstream compat function old new delta dd_main 1469 1543 +74 dd_suffixes 88 112 +24 packed_usage 30156 30176 +20 dd_output_status 372 388 +16 static.status_words - 13 +13 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 4/0 up/down: 147/0) Total: 147 bytes Signed-off-by: Ari Sundholm <ari@tuxera.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/Config.src38
-rw-r--r--coreutils/dd.c143
2 files changed, 111 insertions, 70 deletions
diff --git a/coreutils/Config.src b/coreutils/Config.src
index 68c717883..1bbb91ee9 100644
--- a/coreutils/Config.src
+++ b/coreutils/Config.src
@@ -87,44 +87,6 @@ config CUT
87 cut is used to print selected parts of lines from 87 cut is used to print selected parts of lines from
88 each file to stdout. 88 each file to stdout.
89 89
90config DD
91 bool "dd"
92 default y
93 help
94 dd copies a file (from standard input to standard output,
95 by default) using specific input and output blocksizes,
96 while optionally performing conversions on it.
97
98config FEATURE_DD_SIGNAL_HANDLING
99 bool "Enable DD signal handling for status reporting"
100 default y
101 depends on DD
102 help
103 Sending a SIGUSR1 signal to a running `dd' process makes it
104 print to standard error the number of records read and written
105 so far, then to resume copying.
106
107 $ dd if=/dev/zero of=/dev/null&
108 $ pid=$! kill -USR1 $pid; sleep 1; kill $pid
109 10899206+0 records in
110 10899206+0 records out
111
112config FEATURE_DD_THIRD_STATUS_LINE
113 bool "Enable the third status line upon signal"
114 default y
115 depends on DD && FEATURE_DD_SIGNAL_HANDLING
116 help
117 Displays a coreutils-like third status line with transferred bytes,
118 elapsed time and speed.
119
120config FEATURE_DD_IBS_OBS
121 bool "Enable ibs, obs and conv options"
122 default y
123 depends on DD
124 help
125 Enables support for writing a certain number of bytes in and out,
126 at a time, and performing conversions on the data stream.
127
128config DF 90config DF
129 bool "df" 91 bool "df"
130 default y 92 default y
diff --git a/coreutils/dd.c b/coreutils/dd.c
index 2838f6341..302497074 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -8,6 +8,51 @@
8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9 */ 9 */
10 10
11//config:config DD
12//config: bool "dd"
13//config: default y
14//config: help
15//config: dd copies a file (from standard input to standard output,
16//config: by default) using specific input and output blocksizes,
17//config: while optionally performing conversions on it.
18//config:
19//config:config FEATURE_DD_SIGNAL_HANDLING
20//config: bool "Enable signal handling for status reporting"
21//config: default y
22//config: depends on DD
23//config: help
24//config: Sending a SIGUSR1 signal to a running `dd' process makes it
25//config: print to standard error the number of records read and written
26//config: so far, then to resume copying.
27//config:
28//config: $ dd if=/dev/zero of=/dev/null &
29//config: $ pid=$!; kill -USR1 $pid; sleep 1; kill $pid
30//config: 10899206+0 records in
31//config: 10899206+0 records out
32//config:
33//config:config FEATURE_DD_THIRD_STATUS_LINE
34//config: bool "Enable the third status line upon signal"
35//config: default y
36//config: depends on DD && FEATURE_DD_SIGNAL_HANDLING
37//config: help
38//config: Displays a coreutils-like third status line with transferred bytes,
39//config: elapsed time and speed.
40//config:
41//config:config FEATURE_DD_IBS_OBS
42//config: bool "Enable ibs, obs and conv options"
43//config: default y
44//config: depends on DD
45//config: help
46//config: Enables support for writing a certain number of bytes in and out,
47//config: at a time, and performing conversions on the data stream.
48//config:
49//config:config FEATURE_DD_STATUS
50//config: bool "Enable status display options"
51//config: default y
52//config: depends on DD
53//config: help
54//config: Enables support for status=noxfer/none option.
55
11//usage:#define dd_trivial_usage 56//usage:#define dd_trivial_usage
12//usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" 57//usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n"
13//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") 58//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]")
@@ -32,8 +77,12 @@
32//usage: "\n conv=fsync Physically write data out before finishing" 77//usage: "\n conv=fsync Physically write data out before finishing"
33//usage: "\n conv=swab Swap every pair of bytes" 78//usage: "\n conv=swab Swap every pair of bytes"
34//usage: ) 79//usage: )
80//usage: IF_FEATURE_DD_STATUS(
81//usage: "\n status=noxfer Suppress rate output"
82//usage: "\n status=none Suppress all output"
83//usage: )
35//usage: "\n" 84//usage: "\n"
36//usage: "\nN may be suffixed by c (1), w (2), b (512), kD (1000), k (1024), MD, M, GD, G" 85//usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G"
37//usage: 86//usage:
38//usage:#define dd_example_usage 87//usage:#define dd_example_usage
39//usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" 88//usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n"
@@ -54,13 +103,18 @@ static const struct suffix_mult dd_suffixes[] = {
54 { "c", 1 }, 103 { "c", 1 },
55 { "w", 2 }, 104 { "w", 2 },
56 { "b", 512 }, 105 { "b", 512 },
106 { "kB", 1000 },
57 { "kD", 1000 }, 107 { "kD", 1000 },
58 { "k", 1024 }, 108 { "k", 1024 },
59 { "K", 1024 }, /* compat with coreutils dd */ 109 { "K", 1024 }, /* compat with coreutils dd (it also accepts KB and KD, TODO?) */
110 { "MB", 1000000 },
60 { "MD", 1000000 }, 111 { "MD", 1000000 },
61 { "M", 1048576 }, 112 { "M", 1024*1024 },
113 { "GB", 1000000000 },
62 { "GD", 1000000000 }, 114 { "GD", 1000000000 },
63 { "G", 1073741824 }, 115 { "G", 1024*1024*1024 },
116 /* "D" suffix for decimal is not in coreutils manpage, looks like it's deprecated */
117 /* coreutils also understands TPEZY suffixes for tera- and so on, with B suffix for decimal */
64 { "", 0 } 118 { "", 0 }
65}; 119};
66 120
@@ -70,6 +124,7 @@ struct globals {
70 unsigned long long total_bytes; 124 unsigned long long total_bytes;
71 unsigned long long begin_time_us; 125 unsigned long long begin_time_us;
72#endif 126#endif
127 int flags;
73} FIX_ALIASING; 128} FIX_ALIASING;
74#define G (*(struct globals*)&bb_common_bufsiz1) 129#define G (*(struct globals*)&bb_common_bufsiz1)
75#define INIT_G() do { \ 130#define INIT_G() do { \
@@ -77,6 +132,21 @@ struct globals {
77 memset(&G, 0, sizeof(G)); \ 132 memset(&G, 0, sizeof(G)); \
78} while (0) 133} while (0)
79 134
135enum {
136 /* Must be in the same order as OP_conv_XXX! */
137 /* (see "flags |= (1 << what)" below) */
138 FLAG_NOTRUNC = (1 << 0) * ENABLE_FEATURE_DD_IBS_OBS,
139 FLAG_SYNC = (1 << 1) * ENABLE_FEATURE_DD_IBS_OBS,
140 FLAG_NOERROR = (1 << 2) * ENABLE_FEATURE_DD_IBS_OBS,
141 FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS,
142 FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS,
143 /* end of conv flags */
144 FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
145 FLAG_COUNT = 1 << 6,
146 FLAG_STATUS = 1 << 7,
147 FLAG_STATUS_NONE = 1 << 7,
148 FLAG_STATUS_NOXFER = 1 << 8,
149};
80 150
81static void dd_output_status(int UNUSED_PARAM cur_signal) 151static void dd_output_status(int UNUSED_PARAM cur_signal)
82{ 152{
@@ -93,6 +163,13 @@ static void dd_output_status(int UNUSED_PARAM cur_signal)
93 G.out_full, G.out_part); 163 G.out_full, G.out_part);
94 164
95#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE 165#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
166# if ENABLE_FEATURE_DD_STATUS
167 if (G.flags & FLAG_STATUS_NOXFER) /* status=noxfer active? */
168 return;
169 //TODO: should status=none make dd stop reacting to USR1 entirely?
170 //So far we react to it (we print the stats),
171 //status=none only suppresses final, non-USR1 generated status message.
172# endif
96 fprintf(stderr, "%llu bytes (%sB) copied, ", 173 fprintf(stderr, "%llu bytes (%sB) copied, ",
97 G.total_bytes, 174 G.total_bytes,
98 /* show fractional digit, use suffixes */ 175 /* show fractional digit, use suffixes */
@@ -148,20 +225,8 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs,
148int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 225int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
149int dd_main(int argc UNUSED_PARAM, char **argv) 226int dd_main(int argc UNUSED_PARAM, char **argv)
150{ 227{
151 enum {
152 /* Must be in the same order as OP_conv_XXX! */
153 /* (see "flags |= (1 << what)" below) */
154 FLAG_NOTRUNC = (1 << 0) * ENABLE_FEATURE_DD_IBS_OBS,
155 FLAG_SYNC = (1 << 1) * ENABLE_FEATURE_DD_IBS_OBS,
156 FLAG_NOERROR = (1 << 2) * ENABLE_FEATURE_DD_IBS_OBS,
157 FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS,
158 FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS,
159 /* end of conv flags */
160 FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
161 FLAG_COUNT = 1 << 6,
162 };
163 static const char keywords[] ALIGN1 = 228 static const char keywords[] ALIGN1 =
164 "bs\0""count\0""seek\0""skip\0""if\0""of\0" 229 "bs\0""count\0""seek\0""skip\0""if\0""of\0"IF_FEATURE_DD_STATUS("status\0")
165#if ENABLE_FEATURE_DD_IBS_OBS 230#if ENABLE_FEATURE_DD_IBS_OBS
166 "ibs\0""obs\0""conv\0" 231 "ibs\0""obs\0""conv\0"
167#endif 232#endif
@@ -170,6 +235,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
170 static const char conv_words[] ALIGN1 = 235 static const char conv_words[] ALIGN1 =
171 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; 236 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
172#endif 237#endif
238#if ENABLE_FEATURE_DD_STATUS
239 static const char status_words[] ALIGN1 =
240 "none\0""noxfer\0";
241#endif
173 enum { 242 enum {
174 OP_bs = 0, 243 OP_bs = 0,
175 OP_count, 244 OP_count,
@@ -177,6 +246,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
177 OP_skip, 246 OP_skip,
178 OP_if, 247 OP_if,
179 OP_of, 248 OP_of,
249 IF_FEATURE_DD_STATUS(OP_status,)
180#if ENABLE_FEATURE_DD_IBS_OBS 250#if ENABLE_FEATURE_DD_IBS_OBS
181 OP_ibs, 251 OP_ibs,
182 OP_obs, 252 OP_obs,
@@ -215,14 +285,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
215#endif 285#endif
216 /* These are all zeroed at once! */ 286 /* These are all zeroed at once! */
217 struct { 287 struct {
218 int flags;
219 size_t oc; 288 size_t oc;
220 ssize_t prev_read_size; /* for detecting swab failure */ 289 ssize_t prev_read_size; /* for detecting swab failure */
221 off_t count; 290 off_t count;
222 off_t seek, skip; 291 off_t seek, skip;
223 const char *infile, *outfile; 292 const char *infile, *outfile;
224 } Z; 293 } Z;
225#define flags (Z.flags )
226#define oc (Z.oc ) 294#define oc (Z.oc )
227#define prev_read_size (Z.prev_read_size) 295#define prev_read_size (Z.prev_read_size)
228#define count (Z.count ) 296#define count (Z.count )
@@ -278,7 +346,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
278 n = index_in_strings(conv_words, val); 346 n = index_in_strings(conv_words, val);
279 if (n < 0) 347 if (n < 0)
280 bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv"); 348 bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv");
281 flags |= (1 << n); 349 G.flags |= (1 << n);
282 if (!arg) /* no ',' left, so this was the last specifier */ 350 if (!arg) /* no ',' left, so this was the last specifier */
283 break; 351 break;
284 /* *arg = ','; - to preserve ps listing? */ 352 /* *arg = ','; - to preserve ps listing? */
@@ -294,7 +362,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
294 } 362 }
295 /* These can be large: */ 363 /* These can be large: */
296 if (what == OP_count) { 364 if (what == OP_count) {
297 flags |= FLAG_COUNT; 365 G.flags |= FLAG_COUNT;
298 count = XATOU_SFX(val, dd_suffixes); 366 count = XATOU_SFX(val, dd_suffixes);
299 /*continue;*/ 367 /*continue;*/
300 } 368 }
@@ -314,6 +382,16 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
314 outfile = val; 382 outfile = val;
315 /*continue;*/ 383 /*continue;*/
316 } 384 }
385#if ENABLE_FEATURE_DD_STATUS
386 if (what == OP_status) {
387 int n;
388 n = index_in_strings(status_words, val);
389 if (n < 0)
390 bb_error_msg_and_die(bb_msg_invalid_arg, val, "status");
391 G.flags |= FLAG_STATUS << n;
392 /*continue;*/
393 }
394#endif
317 } /* end of "for (argv[i])" */ 395 } /* end of "for (argv[i])" */
318 396
319//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever 397//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
@@ -321,7 +399,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
321 obuf = ibuf; 399 obuf = ibuf;
322#if ENABLE_FEATURE_DD_IBS_OBS 400#if ENABLE_FEATURE_DD_IBS_OBS
323 if (ibs != obs) { 401 if (ibs != obs) {
324 flags |= FLAG_TWOBUFS; 402 G.flags |= FLAG_TWOBUFS;
325 obuf = xmalloc(obs); 403 obuf = xmalloc(obs);
326 } 404 }
327#endif 405#endif
@@ -341,12 +419,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
341 if (outfile) { 419 if (outfile) {
342 int oflag = O_WRONLY | O_CREAT; 420 int oflag = O_WRONLY | O_CREAT;
343 421
344 if (!seek && !(flags & FLAG_NOTRUNC)) 422 if (!seek && !(G.flags & FLAG_NOTRUNC))
345 oflag |= O_TRUNC; 423 oflag |= O_TRUNC;
346 424
347 xmove_fd(xopen(outfile, oflag), ofd); 425 xmove_fd(xopen(outfile, oflag), ofd);
348 426
349 if (seek && !(flags & FLAG_NOTRUNC)) { 427 if (seek && !(G.flags & FLAG_NOTRUNC)) {
350 if (ftruncate(ofd, seek * obs) < 0) { 428 if (ftruncate(ofd, seek * obs) < 0) {
351 struct stat st; 429 struct stat st;
352 430
@@ -377,7 +455,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
377 goto die_outfile; 455 goto die_outfile;
378 } 456 }
379 457
380 while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { 458 while (!(G.flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) {
381 ssize_t n; 459 ssize_t n;
382 460
383 n = safe_read(ifd, ibuf, ibs); 461 n = safe_read(ifd, ibuf, ibs);
@@ -385,7 +463,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
385 break; 463 break;
386 if (n < 0) { 464 if (n < 0) {
387 /* "Bad block" */ 465 /* "Bad block" */
388 if (!(flags & FLAG_NOERROR)) 466 if (!(G.flags & FLAG_NOERROR))
389 goto die_infile; 467 goto die_infile;
390 bb_simple_perror_msg(infile); 468 bb_simple_perror_msg(infile);
391 /* GNU dd with conv=noerror skips over bad blocks */ 469 /* GNU dd with conv=noerror skips over bad blocks */
@@ -394,7 +472,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
394 * conv=noerror just ignores input bad blocks */ 472 * conv=noerror just ignores input bad blocks */
395 n = 0; 473 n = 0;
396 } 474 }
397 if (flags & FLAG_SWAB) { 475 if (G.flags & FLAG_SWAB) {
398 uint16_t *p16; 476 uint16_t *p16;
399 ssize_t n2; 477 ssize_t n2;
400 478
@@ -419,12 +497,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
419 G.in_full++; 497 G.in_full++;
420 else { 498 else {
421 G.in_part++; 499 G.in_part++;
422 if (flags & FLAG_SYNC) { 500 if (G.flags & FLAG_SYNC) {
423 memset(ibuf + n, 0, ibs - n); 501 memset(ibuf + n, 0, ibs - n);
424 n = ibs; 502 n = ibs;
425 } 503 }
426 } 504 }
427 if (flags & FLAG_TWOBUFS) { 505 if (G.flags & FLAG_TWOBUFS) {
428 char *tmp = ibuf; 506 char *tmp = ibuf;
429 while (n) { 507 while (n) {
430 size_t d = obs - oc; 508 size_t d = obs - oc;
@@ -446,7 +524,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
446 goto out_status; 524 goto out_status;
447 } 525 }
448 526
449 if (flags & FLAG_FSYNC) { 527 if (G.flags & FLAG_FSYNC) {
450 if (fsync(ofd) < 0) 528 if (fsync(ofd) < 0)
451 goto die_outfile; 529 goto die_outfile;
452 } 530 }
@@ -468,11 +546,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
468 546
469 exitcode = EXIT_SUCCESS; 547 exitcode = EXIT_SUCCESS;
470 out_status: 548 out_status:
471 dd_output_status(0); 549 if (!ENABLE_FEATURE_DD_STATUS || !(G.flags & FLAG_STATUS_NONE))
550 dd_output_status(0);
472 551
473 if (ENABLE_FEATURE_CLEAN_UP) { 552 if (ENABLE_FEATURE_CLEAN_UP) {
474 free(obuf); 553 free(obuf);
475 if (flags & FLAG_TWOBUFS) 554 if (G.flags & FLAG_TWOBUFS)
476 free(ibuf); 555 free(ibuf);
477 } 556 }
478 557