diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-08-19 09:01:39 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-08-19 09:01:39 +0200 |
| commit | b941316ae5313be523b64f0a9151ee4decb2b35b (patch) | |
| tree | 9a9d7b7d93214eca477e4fca5a7f2d7c2f05f30d /coreutils | |
| parent | 4b1896cd2ccdb3e09070035f86a48d42b678d8ff (diff) | |
| download | busybox-w32-b941316ae5313be523b64f0a9151ee4decb2b35b.tar.gz busybox-w32-b941316ae5313be523b64f0a9151ee4decb2b35b.tar.bz2 busybox-w32-b941316ae5313be523b64f0a9151ee4decb2b35b.zip | |
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>
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/dd.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c index 9cb96bb06..1732a5c19 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
| @@ -30,10 +30,10 @@ | |||
| 30 | //usage: "\n conv=noerror Continue after read errors" | 30 | //usage: "\n conv=noerror Continue after read errors" |
| 31 | //usage: "\n conv=sync Pad blocks with zeros" | 31 | //usage: "\n conv=sync Pad blocks with zeros" |
| 32 | //usage: "\n conv=fsync Physically write data out before finishing" | 32 | //usage: "\n conv=fsync Physically write data out before finishing" |
| 33 | //usage: "\n conv=swab Swap every pair of bytes" | ||
| 33 | //usage: ) | 34 | //usage: ) |
| 34 | //usage: "\n" | 35 | //usage: "\n" |
| 35 | //usage: "\nNumbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024)," | 36 | //usage: "\nN may be suffixed by c (1), w (2), b (512), kD (1000), k (1024), MD, M, GD, G" |
| 36 | //usage: "\nMD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)" | ||
| 37 | //usage: | 37 | //usage: |
| 38 | //usage:#define dd_example_usage | 38 | //usage:#define dd_example_usage |
| 39 | //usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" | 39 | //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) | |||
| 155 | FLAG_SYNC = 1 << 1, | 155 | FLAG_SYNC = 1 << 1, |
| 156 | FLAG_NOERROR = 1 << 2, | 156 | FLAG_NOERROR = 1 << 2, |
| 157 | FLAG_FSYNC = 1 << 3, | 157 | FLAG_FSYNC = 1 << 3, |
| 158 | FLAG_SWAB = 1 << 4, | ||
| 158 | /* end of conv flags */ | 159 | /* end of conv flags */ |
| 159 | FLAG_TWOBUFS = 1 << 4, | 160 | FLAG_TWOBUFS = 1 << 5, |
| 160 | FLAG_COUNT = 1 << 5, | 161 | FLAG_COUNT = 1 << 6, |
| 161 | }; | 162 | }; |
| 162 | static const char keywords[] ALIGN1 = | 163 | static const char keywords[] ALIGN1 = |
| 163 | "bs\0""count\0""seek\0""skip\0""if\0""of\0" | 164 | "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) | |||
| 167 | ; | 168 | ; |
| 168 | #if ENABLE_FEATURE_DD_IBS_OBS | 169 | #if ENABLE_FEATURE_DD_IBS_OBS |
| 169 | static const char conv_words[] ALIGN1 = | 170 | static const char conv_words[] ALIGN1 = |
| 170 | "notrunc\0""sync\0""noerror\0""fsync\0"; | 171 | "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; |
| 171 | #endif | 172 | #endif |
| 172 | enum { | 173 | enum { |
| 173 | OP_bs = 0, | 174 | OP_bs = 0, |
| @@ -185,11 +186,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
| 185 | OP_conv_sync, | 186 | OP_conv_sync, |
| 186 | OP_conv_noerror, | 187 | OP_conv_noerror, |
| 187 | OP_conv_fsync, | 188 | OP_conv_fsync, |
| 189 | OP_conv_swab, | ||
| 188 | /* Unimplemented conv=XXX: */ | 190 | /* Unimplemented conv=XXX: */ |
| 189 | //nocreat do not create the output file | 191 | //nocreat do not create the output file |
| 190 | //excl fail if the output file already exists | 192 | //excl fail if the output file already exists |
| 191 | //fdatasync physically write output file data before finishing | 193 | //fdatasync physically write output file data before finishing |
| 192 | //swab swap every pair of input bytes | ||
| 193 | //lcase change upper case to lower case | 194 | //lcase change upper case to lower case |
| 194 | //ucase change lower case to upper case | 195 | //ucase change lower case to upper case |
| 195 | //block pad newline-terminated records with spaces to cbs-size | 196 | //block pad newline-terminated records with spaces to cbs-size |
| @@ -197,6 +198,8 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
| 197 | //ascii from EBCDIC to ASCII | 198 | //ascii from EBCDIC to ASCII |
| 198 | //ebcdic from ASCII to EBCDIC | 199 | //ebcdic from ASCII to EBCDIC |
| 199 | //ibm from ASCII to alternate EBCDIC | 200 | //ibm from ASCII to alternate EBCDIC |
| 201 | /* Partially implemented: */ | ||
| 202 | //swab swap every pair of input bytes: will abort on non-even reads | ||
| 200 | #endif | 203 | #endif |
| 201 | }; | 204 | }; |
| 202 | int exitcode = EXIT_FAILURE; | 205 | int exitcode = EXIT_FAILURE; |
| @@ -377,6 +380,20 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
| 377 | * conv=noerror just ignores input bad blocks */ | 380 | * conv=noerror just ignores input bad blocks */ |
| 378 | n = 0; | 381 | n = 0; |
| 379 | } | 382 | } |
| 383 | if (flags & FLAG_SWAB) { | ||
| 384 | /* If n is odd, last byte is not swapped: | ||
| 385 | * echo -n "qwe" | dd conv=swab bs=1 | ||
| 386 | * prints "wqe". | ||
| 387 | * The code does not handle correctly odd-sized reads | ||
| 388 | * in the *middle* of the input. FIXME. | ||
| 389 | */ | ||
| 390 | uint16_t *p16 = (void*) ibuf; | ||
| 391 | uint16_t *end = (void*) (ibuf + (n & ~(ssize_t)1)); | ||
| 392 | while (p16 < end) { | ||
| 393 | *p16 = bswap_16(*p16); | ||
| 394 | p16++; | ||
| 395 | } | ||
| 396 | } | ||
| 380 | if ((size_t)n == ibs) | 397 | if ((size_t)n == ibs) |
| 381 | G.in_full++; | 398 | G.in_full++; |
| 382 | else { | 399 | else { |
