diff options
-rw-r--r-- | package/utils/busybox/patches/008-backport-dd-conv-swab.patch | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/package/utils/busybox/patches/008-backport-dd-conv-swab.patch b/package/utils/busybox/patches/008-backport-dd-conv-swab.patch new file mode 100644 index 0000000000..1e3cd15c93 --- /dev/null +++ b/package/utils/busybox/patches/008-backport-dd-conv-swab.patch @@ -0,0 +1,97 @@ +--- a/coreutils/dd.c ++++ b/coreutils/dd.c +@@ -10,7 +10,7 @@ + + //usage:#define dd_trivial_usage + //usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" +-//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") ++//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync|swab]") + //usage:#define dd_full_usage "\n\n" + //usage: "Copy a file with converting and formatting\n" + //usage: "\n if=FILE Read from FILE instead of stdin" +@@ -30,6 +30,7 @@ + //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)," +@@ -155,9 +156,10 @@ int dd_main(int argc UNUSED_PARAM, char + 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 +169,7 @@ int dd_main(int argc UNUSED_PARAM, char + ; + #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 +187,11 @@ int dd_main(int argc UNUSED_PARAM, char + 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 +@@ -207,12 +209,14 @@ int dd_main(int argc UNUSED_PARAM, char + struct { + int flags; + size_t oc; ++ ssize_t prev_read_size; /* for detecting swab failure */ + off_t count; + off_t seek, skip; + const char *infile, *outfile; + } Z; + #define flags (Z.flags ) + #define oc (Z.oc ) ++#define prev_read_size (Z.prev_read_size) + #define count (Z.count ) + #define seek (Z.seek ) + #define skip (Z.skip ) +@@ -375,6 +379,27 @@ int dd_main(int argc UNUSED_PARAM, char + * conv=noerror just ignores input bad blocks */ + n = 0; + } ++ if (flags & FLAG_SWAB) { ++ uint16_t *p16; ++ ssize_t n2; ++ ++ /* Our code allows only last read to be odd-sized */ ++ if (prev_read_size & 1) ++ bb_error_msg_and_die("can't swab %lu byte buffer", ++ (unsigned long)prev_read_size); ++ prev_read_size = n; ++ ++ /* If n is odd, last byte is not swapped: ++ * echo -n "qwe" | dd conv=swab ++ * prints "wqe". ++ */ ++ p16 = (void*) ibuf; ++ n2 = (n >> 1); ++ while (--n2 >= 0) { ++ *p16 = bswap_16(*p16); ++ p16++; ++ } ++ } + if ((size_t)n == ibs) + G.in_full++; + else { |