[git commit] dd: support conv=swab

Denys Vlasenko vda.linux at googlemail.com
Mon Aug 19 07:01:39 UTC 2013


commit: http://git.busybox.net/busybox/commit/?id=b941316ae5313be523b64f0a9151ee4decb2b35b
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
dd_main                                             1482    1520     +38
static.conv_words                                     28      33      +5
packed_usage                                       29377   29375      -2

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 coreutils/dd.c |   29 +++++++++++++++++++++++------
 1 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/coreutils/dd.c b/coreutils/dd.c
index 9cb96bb..1732a5c 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -30,10 +30,10 @@
 //usage:     "\n	conv=noerror	Continue after read errors"
 //usage:     "\n	conv=sync	Pad blocks with zeros"
 //usage:     "\n	conv=fsync	Physically write data out before finishing"
+//usage:     "\n	conv=swab	Swap every pair of bytes"
 //usage:	)
 //usage:     "\n"
-//usage:     "\nNumbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),"
-//usage:     "\nMD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)"
+//usage:     "\nN may be suffixed by c (1), w (2), b (512), kD (1000), k (1024), MD, M, GD, G"
 //usage:
 //usage:#define dd_example_usage
 //usage:       "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n"
@@ -155,9 +155,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 		FLAG_SYNC    = 1 << 1,
 		FLAG_NOERROR = 1 << 2,
 		FLAG_FSYNC   = 1 << 3,
+		FLAG_SWAB    = 1 << 4,
 		/* end of conv flags */
-		FLAG_TWOBUFS = 1 << 4,
-		FLAG_COUNT   = 1 << 5,
+		FLAG_TWOBUFS = 1 << 5,
+		FLAG_COUNT   = 1 << 6,
 	};
 	static const char keywords[] ALIGN1 =
 		"bs\0""count\0""seek\0""skip\0""if\0""of\0"
@@ -167,7 +168,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 		;
 #if ENABLE_FEATURE_DD_IBS_OBS
 	static const char conv_words[] ALIGN1 =
-		"notrunc\0""sync\0""noerror\0""fsync\0";
+		"notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
 #endif
 	enum {
 		OP_bs = 0,
@@ -185,11 +186,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 		OP_conv_sync,
 		OP_conv_noerror,
 		OP_conv_fsync,
+		OP_conv_swab,
 	/* Unimplemented conv=XXX: */
 	//nocreat       do not create the output file
 	//excl          fail if the output file already exists
 	//fdatasync     physically write output file data before finishing
-	//swab          swap every pair of input bytes
 	//lcase         change upper case to lower case
 	//ucase         change lower case to upper case
 	//block         pad newline-terminated records with spaces to cbs-size
@@ -197,6 +198,8 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 	//ascii         from EBCDIC to ASCII
 	//ebcdic        from ASCII to EBCDIC
 	//ibm           from ASCII to alternate EBCDIC
+	/* Partially implemented: */
+	//swab          swap every pair of input bytes: will abort on non-even reads
 #endif
 	};
 	int exitcode = EXIT_FAILURE;
@@ -377,6 +380,20 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
 			 * conv=noerror just ignores input bad blocks */
 			n = 0;
 		}
+		if (flags & FLAG_SWAB) {
+			/* If n is odd, last byte is not swapped:
+			 *  echo -n "qwe" | dd conv=swab bs=1
+			 * prints "wqe".
+			 * The code does not handle correctly odd-sized reads
+			 * in the *middle* of the input. FIXME.
+			 */
+			uint16_t *p16 = (void*) ibuf;
+			uint16_t *end = (void*) (ibuf + (n & ~(ssize_t)1));
+			while (p16 < end) {
+				*p16 = bswap_16(*p16);
+				p16++;
+			}
+		}
 		if ((size_t)n == ibs)
 			G.in_full++;
 		else {


More information about the busybox-cvs mailing list