1e3cd15c93f92aafce6611c496b6726310e09bfb
[openwrt/svn-archive/archive.git] / package / utils / busybox / patches / 008-backport-dd-conv-swab.patch
1 --- a/coreutils/dd.c
2 +++ b/coreutils/dd.c
3 @@ -10,7 +10,7 @@
4
5 //usage:#define dd_trivial_usage
6 //usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n"
7 -//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]")
8 +//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync|swab]")
9 //usage:#define dd_full_usage "\n\n"
10 //usage: "Copy a file with converting and formatting\n"
11 //usage: "\n if=FILE Read from FILE instead of stdin"
12 @@ -30,6 +30,7 @@
13 //usage: "\n conv=noerror Continue after read errors"
14 //usage: "\n conv=sync Pad blocks with zeros"
15 //usage: "\n conv=fsync Physically write data out before finishing"
16 +//usage: "\n conv=swab Swap every pair of bytes"
17 //usage: )
18 //usage: "\n"
19 //usage: "\nNumbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),"
20 @@ -155,9 +156,10 @@ int dd_main(int argc UNUSED_PARAM, char
21 FLAG_SYNC = 1 << 1,
22 FLAG_NOERROR = 1 << 2,
23 FLAG_FSYNC = 1 << 3,
24 + FLAG_SWAB = 1 << 4,
25 /* end of conv flags */
26 - FLAG_TWOBUFS = 1 << 4,
27 - FLAG_COUNT = 1 << 5,
28 + FLAG_TWOBUFS = 1 << 5,
29 + FLAG_COUNT = 1 << 6,
30 };
31 static const char keywords[] ALIGN1 =
32 "bs\0""count\0""seek\0""skip\0""if\0""of\0"
33 @@ -167,7 +169,7 @@ int dd_main(int argc UNUSED_PARAM, char
34 ;
35 #if ENABLE_FEATURE_DD_IBS_OBS
36 static const char conv_words[] ALIGN1 =
37 - "notrunc\0""sync\0""noerror\0""fsync\0";
38 + "notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
39 #endif
40 enum {
41 OP_bs = 0,
42 @@ -185,11 +187,11 @@ int dd_main(int argc UNUSED_PARAM, char
43 OP_conv_sync,
44 OP_conv_noerror,
45 OP_conv_fsync,
46 + OP_conv_swab,
47 /* Unimplemented conv=XXX: */
48 //nocreat do not create the output file
49 //excl fail if the output file already exists
50 //fdatasync physically write output file data before finishing
51 - //swab swap every pair of input bytes
52 //lcase change upper case to lower case
53 //ucase change lower case to upper case
54 //block pad newline-terminated records with spaces to cbs-size
55 @@ -207,12 +209,14 @@ int dd_main(int argc UNUSED_PARAM, char
56 struct {
57 int flags;
58 size_t oc;
59 + ssize_t prev_read_size; /* for detecting swab failure */
60 off_t count;
61 off_t seek, skip;
62 const char *infile, *outfile;
63 } Z;
64 #define flags (Z.flags )
65 #define oc (Z.oc )
66 +#define prev_read_size (Z.prev_read_size)
67 #define count (Z.count )
68 #define seek (Z.seek )
69 #define skip (Z.skip )
70 @@ -375,6 +379,27 @@ int dd_main(int argc UNUSED_PARAM, char
71 * conv=noerror just ignores input bad blocks */
72 n = 0;
73 }
74 + if (flags & FLAG_SWAB) {
75 + uint16_t *p16;
76 + ssize_t n2;
77 +
78 + /* Our code allows only last read to be odd-sized */
79 + if (prev_read_size & 1)
80 + bb_error_msg_and_die("can't swab %lu byte buffer",
81 + (unsigned long)prev_read_size);
82 + prev_read_size = n;
83 +
84 + /* If n is odd, last byte is not swapped:
85 + * echo -n "qwe" | dd conv=swab
86 + * prints "wqe".
87 + */
88 + p16 = (void*) ibuf;
89 + n2 = (n >> 1);
90 + while (--n2 >= 0) {
91 + *p16 = bswap_16(*p16);
92 + p16++;
93 + }
94 + }
95 if ((size_t)n == ibs)
96 G.in_full++;
97 else {