dd: support conv=swab
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@googlemail.com>
This commit is contained in:
		@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user