aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nicholas.clark@gmail.com>2018-01-25 19:00:19 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-01-25 19:00:19 +0100
commit77a6678c427db5ea15d6d0005a579f441277df06 (patch)
tree3dc09cfe78a10443d20ce3d35dac71b9101fc34d
parent043be556916ab0fbbece9d406cef199d397f8455 (diff)
downloadbusybox-w32-77a6678c427db5ea15d6d0005a579f441277df06.tar.gz
busybox-w32-77a6678c427db5ea15d6d0005a579f441277df06.tar.bz2
busybox-w32-77a6678c427db5ea15d6d0005a579f441277df06.zip
dd: add 'fullblock' iflag
Adds a fullblock iflag for improved compatibility with GNU dd. The new iflag can be used to ensure that dd calls retrieve the expected amount of data when reading from pipes or unusual filesystems. function old new delta packed_usage 32249 32334 +85 dd_main 1582 1632 +50 static.iflag_words 12 22 +10 ------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 145/0) Total: 145 bytes Signed-off-by: Nicholas Clark <nicholas.clark@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--coreutils/dd.c33
-rw-r--r--docs/posix_conformance.txt5
2 files changed, 26 insertions, 12 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c
index 38b2a6aa1..0f130bcad 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -37,7 +37,7 @@
37//config: elapsed time and speed. 37//config: elapsed time and speed.
38//config: 38//config:
39//config:config FEATURE_DD_IBS_OBS 39//config:config FEATURE_DD_IBS_OBS
40//config: bool "Enable ibs, obs and conv options" 40//config: bool "Enable ibs, obs, iflag and conv options"
41//config: default y 41//config: default y
42//config: depends on DD 42//config: depends on DD
43//config: help 43//config: help
@@ -57,7 +57,7 @@
57 57
58//usage:#define dd_trivial_usage 58//usage:#define dd_trivial_usage
59//usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" 59//usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n"
60//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes]") 60//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes|fullblock]")
61//usage:#define dd_full_usage "\n\n" 61//usage:#define dd_full_usage "\n\n"
62//usage: "Copy a file with converting and formatting\n" 62//usage: "Copy a file with converting and formatting\n"
63//usage: "\n if=FILE Read from FILE instead of stdin" 63//usage: "\n if=FILE Read from FILE instead of stdin"
@@ -79,6 +79,7 @@
79//usage: "\n conv=fsync Physically write data out before finishing" 79//usage: "\n conv=fsync Physically write data out before finishing"
80//usage: "\n conv=swab Swap every pair of bytes" 80//usage: "\n conv=swab Swap every pair of bytes"
81//usage: "\n iflag=skip_bytes skip=N is in bytes" 81//usage: "\n iflag=skip_bytes skip=N is in bytes"
82//usage: "\n iflag=fullblock Read full blocks"
82//usage: ) 83//usage: )
83//usage: IF_FEATURE_DD_STATUS( 84//usage: IF_FEATURE_DD_STATUS(
84//usage: "\n status=noxfer Suppress rate output" 85//usage: "\n status=noxfer Suppress rate output"
@@ -130,11 +131,12 @@ enum {
130 /* start of input flags */ 131 /* start of input flags */
131 FLAG_IFLAG_SHIFT = 5, 132 FLAG_IFLAG_SHIFT = 5,
132 FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, 133 FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
134 FLAG_FULLBLOCK = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS,
133 /* end of input flags */ 135 /* end of input flags */
134 FLAG_TWOBUFS = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS, 136 FLAG_TWOBUFS = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS,
135 FLAG_COUNT = 1 << 7, 137 FLAG_COUNT = 1 << 8,
136 FLAG_STATUS_NONE = 1 << 8, 138 FLAG_STATUS_NONE = 1 << 9,
137 FLAG_STATUS_NOXFER = 1 << 9, 139 FLAG_STATUS_NOXFER = 1 << 10,
138}; 140};
139 141
140static void dd_output_status(int UNUSED_PARAM cur_signal) 142static void dd_output_status(int UNUSED_PARAM cur_signal)
@@ -255,7 +257,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
255 static const char conv_words[] ALIGN1 = 257 static const char conv_words[] ALIGN1 =
256 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; 258 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
257 static const char iflag_words[] ALIGN1 = 259 static const char iflag_words[] ALIGN1 =
258 "skip_bytes\0"; 260 "skip_bytes\0""fullblock\0";
259#endif 261#endif
260#if ENABLE_FEATURE_DD_STATUS 262#if ENABLE_FEATURE_DD_STATUS
261 static const char status_words[] ALIGN1 = 263 static const char status_words[] ALIGN1 =
@@ -294,6 +296,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
294 /* Partially implemented: */ 296 /* Partially implemented: */
295 //swab swap every pair of input bytes: will abort on non-even reads 297 //swab swap every pair of input bytes: will abort on non-even reads
296 OP_iflag_skip_bytes, 298 OP_iflag_skip_bytes,
299 OP_iflag_fullblock,
297#endif 300#endif
298 }; 301 };
299 smallint exitcode = EXIT_FAILURE; 302 smallint exitcode = EXIT_FAILURE;
@@ -454,7 +457,13 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
454 size_t blocksz = (G.flags & FLAG_SKIP_BYTES) ? 1 : ibs; 457 size_t blocksz = (G.flags & FLAG_SKIP_BYTES) ? 1 : ibs;
455 if (lseek(ifd, skip * blocksz, SEEK_CUR) < 0) { 458 if (lseek(ifd, skip * blocksz, SEEK_CUR) < 0) {
456 do { 459 do {
457 ssize_t n = safe_read(ifd, ibuf, blocksz); 460 ssize_t n;
461#if ENABLE_FEATURE_DD_IBS_OBS
462 if (G.flags & FLAG_FULLBLOCK)
463 n = full_read(ifd, ibuf, blocksz);
464 else
465#endif
466 n = safe_read(ifd, ibuf, blocksz);
458 if (n < 0) 467 if (n < 0)
459 goto die_infile; 468 goto die_infile;
460 if (n == 0) 469 if (n == 0)
@@ -469,8 +478,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
469 478
470 while (!(G.flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { 479 while (!(G.flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) {
471 ssize_t n; 480 ssize_t n;
472 481#if ENABLE_FEATURE_DD_IBS_OBS
473 n = safe_read(ifd, ibuf, ibs); 482 if (G.flags & FLAG_FULLBLOCK)
483 n = full_read(ifd, ibuf, ibs);
484 else
485#endif
486 n = safe_read(ifd, ibuf, ibs);
474 if (n == 0) 487 if (n == 0)
475 break; 488 break;
476 if (n < 0) { 489 if (n < 0) {
diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt
index 8b9112020..cdf89b744 100644
--- a/docs/posix_conformance.txt
+++ b/docs/posix_conformance.txt
@@ -178,9 +178,10 @@ dd POSIX options:
178 conv=noerror | yes | | 178 conv=noerror | yes | |
179 conv=notrunc | yes | | 179 conv=notrunc | yes | |
180 conv=sync | yes | | 180 conv=sync | yes | |
181dd compatibility options:
182 conv=fsync | yes | |
181 iflag=skip_bytes| yes | | 183 iflag=skip_bytes| yes | |
182dd Busybox specific options: 184 iflag=fullblock | yes | |
183 conv=fsync
184 185
185df POSIX options 186df POSIX options
186 option | exists | compliant | remarks 187 option | exists | compliant | remarks