[git commit] dd: add 'fullblock' iflag

Denys Vlasenko vda.linux at googlemail.com
Thu Jan 25 18:00:19 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=77a6678c427db5ea15d6d0005a579f441277df06
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 coreutils/dd.c             | 33 +++++++++++++++++++++++----------
 docs/posix_conformance.txt |  5 +++--
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/coreutils/dd.c b/coreutils/dd.c
index 38b2a6a..0f130bc 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -37,7 +37,7 @@
 //config:	elapsed time and speed.
 //config:
 //config:config FEATURE_DD_IBS_OBS
-//config:	bool "Enable ibs, obs and conv options"
+//config:	bool "Enable ibs, obs, iflag and conv options"
 //config:	default y
 //config:	depends on DD
 //config:	help
@@ -57,7 +57,7 @@
 
 //usage:#define dd_trivial_usage
 //usage:       "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n"
-//usage:       "	[seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes]")
+//usage:       "	[seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes|fullblock]")
 //usage:#define dd_full_usage "\n\n"
 //usage:       "Copy a file with converting and formatting\n"
 //usage:     "\n	if=FILE		Read from FILE instead of stdin"
@@ -79,6 +79,7 @@
 //usage:     "\n	conv=fsync	Physically write data out before finishing"
 //usage:     "\n	conv=swab	Swap every pair of bytes"
 //usage:     "\n	iflag=skip_bytes	skip=N is in bytes"
+//usage:     "\n	iflag=fullblock	Read full blocks"
 //usage:	)
 //usage:	IF_FEATURE_DD_STATUS(
 //usage:     "\n	status=noxfer	Suppress rate output"
@@ -130,11 +131,12 @@ enum {
 	/* start of input flags */
 	FLAG_IFLAG_SHIFT = 5,
 	FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
+	FLAG_FULLBLOCK = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS,
 	/* end of input flags */
-	FLAG_TWOBUFS = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS,
-	FLAG_COUNT   = 1 << 7,
-	FLAG_STATUS_NONE = 1 << 8,
-	FLAG_STATUS_NOXFER = 1 << 9,
+	FLAG_TWOBUFS = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS,
+	FLAG_COUNT   = 1 << 8,
+	FLAG_STATUS_NONE = 1 << 9,
+	FLAG_STATUS_NOXFER = 1 << 10,
 };
 
 static void dd_output_status(int UNUSED_PARAM cur_signal)
@@ -255,7 +257,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 	static const char conv_words[] ALIGN1 =
 		"notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
 	static const char iflag_words[] ALIGN1 =
-		"skip_bytes\0";
+		"skip_bytes\0""fullblock\0";
 #endif
 #if ENABLE_FEATURE_DD_STATUS
 	static const char status_words[] ALIGN1 =
@@ -294,6 +296,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 	/* Partially implemented: */
 	//swab          swap every pair of input bytes: will abort on non-even reads
 		OP_iflag_skip_bytes,
+		OP_iflag_fullblock,
 #endif
 	};
 	smallint exitcode = EXIT_FAILURE;
@@ -454,7 +457,13 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 		size_t blocksz = (G.flags & FLAG_SKIP_BYTES) ? 1 : ibs;
 		if (lseek(ifd, skip * blocksz, SEEK_CUR) < 0) {
 			do {
-				ssize_t n = safe_read(ifd, ibuf, blocksz);
+				ssize_t n;
+#if ENABLE_FEATURE_DD_IBS_OBS
+				if (G.flags & FLAG_FULLBLOCK)
+					n = full_read(ifd, ibuf, blocksz);
+				else
+#endif
+					n = safe_read(ifd, ibuf, blocksz);
 				if (n < 0)
 					goto die_infile;
 				if (n == 0)
@@ -469,8 +478,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 
 	while (!(G.flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) {
 		ssize_t n;
-
-		n = safe_read(ifd, ibuf, ibs);
+#if ENABLE_FEATURE_DD_IBS_OBS
+		if (G.flags & FLAG_FULLBLOCK)
+			n = full_read(ifd, ibuf, ibs);
+		else
+#endif
+			n = safe_read(ifd, ibuf, ibs);
 		if (n == 0)
 			break;
 		if (n < 0) {
diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt
index 8b91120..cdf89b7 100644
--- a/docs/posix_conformance.txt
+++ b/docs/posix_conformance.txt
@@ -178,9 +178,10 @@ dd POSIX options:
   conv=noerror    |  yes   |           |
   conv=notrunc    |  yes   |           |
   conv=sync       |  yes   |           |
+dd compatibility options:
+  conv=fsync      |  yes   |           |
   iflag=skip_bytes|  yes   |           |
-dd Busybox specific options:
- conv=fsync
+  iflag=fullblock |  yes   |           |
 
 df POSIX options
  option           | exists | compliant | remarks


More information about the busybox-cvs mailing list