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:
Denys Vlasenko 2013-08-19 09:01:39 +02:00
parent 4b1896cd2c
commit b941316ae5

View File

@ -30,10 +30,10 @@
//usage: "\n conv=noerror Continue after read errors" //usage: "\n conv=noerror Continue after read errors"
//usage: "\n conv=sync Pad blocks with zeros" //usage: "\n conv=sync Pad blocks with zeros"
//usage: "\n conv=fsync Physically write data out before finishing" //usage: "\n conv=fsync Physically write data out before finishing"
//usage: "\n conv=swab Swap every pair of bytes"
//usage: ) //usage: )
//usage: "\n" //usage: "\n"
//usage: "\nNumbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024)," //usage: "\nN may be suffixed by c (1), w (2), b (512), kD (1000), k (1024), MD, M, GD, G"
//usage: "\nMD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)"
//usage: //usage:
//usage:#define dd_example_usage //usage:#define dd_example_usage
//usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" //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_SYNC = 1 << 1,
FLAG_NOERROR = 1 << 2, FLAG_NOERROR = 1 << 2,
FLAG_FSYNC = 1 << 3, FLAG_FSYNC = 1 << 3,
FLAG_SWAB = 1 << 4,
/* end of conv flags */ /* end of conv flags */
FLAG_TWOBUFS = 1 << 4, FLAG_TWOBUFS = 1 << 5,
FLAG_COUNT = 1 << 5, FLAG_COUNT = 1 << 6,
}; };
static const char keywords[] ALIGN1 = static const char keywords[] ALIGN1 =
"bs\0""count\0""seek\0""skip\0""if\0""of\0" "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 #if ENABLE_FEATURE_DD_IBS_OBS
static const char conv_words[] ALIGN1 = 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 #endif
enum { enum {
OP_bs = 0, OP_bs = 0,
@ -185,11 +186,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
OP_conv_sync, OP_conv_sync,
OP_conv_noerror, OP_conv_noerror,
OP_conv_fsync, OP_conv_fsync,
OP_conv_swab,
/* Unimplemented conv=XXX: */ /* Unimplemented conv=XXX: */
//nocreat do not create the output file //nocreat do not create the output file
//excl fail if the output file already exists //excl fail if the output file already exists
//fdatasync physically write output file data before finishing //fdatasync physically write output file data before finishing
//swab swap every pair of input bytes
//lcase change upper case to lower case //lcase change upper case to lower case
//ucase change lower case to upper case //ucase change lower case to upper case
//block pad newline-terminated records with spaces to cbs-size //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 //ascii from EBCDIC to ASCII
//ebcdic from ASCII to EBCDIC //ebcdic from ASCII to EBCDIC
//ibm from ASCII to alternate EBCDIC //ibm from ASCII to alternate EBCDIC
/* Partially implemented: */
//swab swap every pair of input bytes: will abort on non-even reads
#endif #endif
}; };
int exitcode = EXIT_FAILURE; int exitcode = EXIT_FAILURE;
@ -377,6 +380,20 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
* conv=noerror just ignores input bad blocks */ * conv=noerror just ignores input bad blocks */
n = 0; 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) if ((size_t)n == ibs)
G.in_full++; G.in_full++;
else { else {