dd: support conv=swab
No binary (build failed)
—
(log yok)
| @@ -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 { | |