aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/dd.c29
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 {