aboutsummaryrefslogtreecommitdiff
path: root/coreutils/dd.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/dd.c')
-rw-r--r--coreutils/dd.c61
1 files changed, 53 insertions, 8 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c
index c032ebe1b..51f3adf24 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -59,8 +59,13 @@
59//usage: "[if=FILE] [of=FILE] [" IF_FEATURE_DD_IBS_OBS("ibs=N obs=N/") "bs=N] [count=N] [skip=N] [seek=N]" 59//usage: "[if=FILE] [of=FILE] [" IF_FEATURE_DD_IBS_OBS("ibs=N obs=N/") "bs=N] [count=N] [skip=N] [seek=N]"
60//usage: IF_FEATURE_DD_IBS_OBS("\n" 60//usage: IF_FEATURE_DD_IBS_OBS("\n"
61//usage: " [conv=notrunc|noerror|sync|fsync]\n" 61//usage: " [conv=notrunc|noerror|sync|fsync]\n"
62//usage: IF_NOT_PLATFORM_MINGW32(
62//usage: " [iflag=skip_bytes|count_bytes|fullblock|direct] [oflag=seek_bytes|append|direct]" 63//usage: " [iflag=skip_bytes|count_bytes|fullblock|direct] [oflag=seek_bytes|append|direct]"
63//usage: ) 64//usage: )
65//usage: IF_PLATFORM_MINGW32(
66//usage: " [iflag=skip_bytes|count_bytes|fullblock] [oflag=seek_bytes|append]"
67//usage: )
68//usage: )
64//usage:#define dd_full_usage "\n\n" 69//usage:#define dd_full_usage "\n\n"
65//usage: "Copy a file with converting and formatting\n" 70//usage: "Copy a file with converting and formatting\n"
66//usage: "\n if=FILE Read from FILE instead of stdin" 71//usage: "\n if=FILE Read from FILE instead of stdin"
@@ -84,8 +89,10 @@
84//usage: "\n iflag=skip_bytes skip=N is in bytes" 89//usage: "\n iflag=skip_bytes skip=N is in bytes"
85//usage: "\n iflag=count_bytes count=N is in bytes" 90//usage: "\n iflag=count_bytes count=N is in bytes"
86//usage: "\n oflag=seek_bytes seek=N is in bytes" 91//usage: "\n oflag=seek_bytes seek=N is in bytes"
92//usage: IF_NOT_PLATFORM_MINGW32(
87//usage: "\n iflag=direct O_DIRECT input" 93//usage: "\n iflag=direct O_DIRECT input"
88//usage: "\n oflag=direct O_DIRECT output" 94//usage: "\n oflag=direct O_DIRECT output"
95//usage: )
89//usage: "\n iflag=fullblock Read full blocks" 96//usage: "\n iflag=fullblock Read full blocks"
90//usage: "\n oflag=append Open output in append mode" 97//usage: "\n oflag=append Open output in append mode"
91//usage: ) 98//usage: )
@@ -94,6 +101,9 @@
94//usage: "\n status=none Suppress all output" 101//usage: "\n status=none Suppress all output"
95//usage: ) 102//usage: )
96//usage: "\n" 103//usage: "\n"
104//usage: IF_PLATFORM_MINGW32(
105//usage: "\nif=/dev/zero and if=/dev/urandom are supported"
106//usage: )
97//usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G" 107//usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G"
98//usage: 108//usage:
99//usage:#define dd_example_usage 109//usage:#define dd_example_usage
@@ -104,6 +114,10 @@
104#include "libbb.h" 114#include "libbb.h"
105#include "common_bufsiz.h" 115#include "common_bufsiz.h"
106 116
117#if ENABLE_PLATFORM_MINGW32
118# undef O_DIRECT
119#endif
120
107/* This is a NOEXEC applet. Be very careful! */ 121/* This is a NOEXEC applet. Be very careful! */
108 122
109 123
@@ -141,13 +155,13 @@ enum {
141 FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, 155 FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
142 FLAG_COUNT_BYTES = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS, 156 FLAG_COUNT_BYTES = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS,
143 FLAG_FULLBLOCK = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS, 157 FLAG_FULLBLOCK = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS,
144 FLAG_IDIRECT = (1 << 8) * ENABLE_FEATURE_DD_IBS_OBS, 158 FLAG_IDIRECT = (1 << 8) * ENABLE_FEATURE_DD_IBS_OBS * ENABLE_PLATFORM_POSIX,
145 /* end of input flags */ 159 /* end of input flags */
146 /* start of output flags */ 160 /* start of output flags */
147 FLAG_OFLAG_SHIFT = 9, 161 FLAG_OFLAG_SHIFT = 9,
148 FLAG_SEEK_BYTES = (1 << 9) * ENABLE_FEATURE_DD_IBS_OBS, 162 FLAG_SEEK_BYTES = (1 << 9) * ENABLE_FEATURE_DD_IBS_OBS,
149 FLAG_APPEND = (1 << 10) * ENABLE_FEATURE_DD_IBS_OBS, 163 FLAG_APPEND = (1 << 10) * ENABLE_FEATURE_DD_IBS_OBS,
150 FLAG_ODIRECT = (1 << 11) * ENABLE_FEATURE_DD_IBS_OBS, 164 FLAG_ODIRECT = (1 << 11) * ENABLE_FEATURE_DD_IBS_OBS * ENABLE_PLATFORM_POSIX,
151 /* end of output flags */ 165 /* end of output flags */
152 FLAG_TWOBUFS = (1 << 12) * ENABLE_FEATURE_DD_IBS_OBS, 166 FLAG_TWOBUFS = (1 << 12) * ENABLE_FEATURE_DD_IBS_OBS,
153 FLAG_COUNT = 1 << 13, 167 FLAG_COUNT = 1 << 13,
@@ -220,7 +234,9 @@ static ssize_t dd_read(void *ibuf, size_t ibs)
220 ssize_t n; 234 ssize_t n;
221 235
222#if ENABLE_FEATURE_DD_IBS_OBS 236#if ENABLE_FEATURE_DD_IBS_OBS
237# if !ENABLE_PLATFORM_MINGW32
223 read_again: 238 read_again:
239# endif
224 if (G.flags & FLAG_FULLBLOCK) 240 if (G.flags & FLAG_FULLBLOCK)
225 n = full_read(ifd, ibuf, ibs); 241 n = full_read(ifd, ibuf, ibs);
226 else 242 else
@@ -240,7 +256,9 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs,
240{ 256{
241 ssize_t n; 257 ssize_t n;
242 258
259#if !ENABLE_PLATFORM_MINGW32
243 IF_FEATURE_DD_IBS_OBS(write_again:) 260 IF_FEATURE_DD_IBS_OBS(write_again:)
261#endif
244 n = full_write(ofd, buf, len); 262 n = full_write(ofd, buf, len);
245#if ENABLE_FEATURE_DD_IBS_OBS 263#if ENABLE_FEATURE_DD_IBS_OBS
246# ifdef O_DIRECT 264# ifdef O_DIRECT
@@ -307,9 +325,11 @@ static int parse_comma_flags(char *val, const char *words, const char *error_in)
307 325
308static void *alloc_buf(size_t size) 326static void *alloc_buf(size_t size)
309{ 327{
328#if !ENABLE_PLATFORM_MINGW32
310 /* Important for "{i,o}flag=direct" - buffers must be page aligned */ 329 /* Important for "{i,o}flag=direct" - buffers must be page aligned */
311 if (size >= bb_getpagesize()) 330 if (size >= bb_getpagesize())
312 return xmmap_anon(size); 331 return xmmap_anon(size);
332#endif
313 return xmalloc(size); 333 return xmalloc(size);
314} 334}
315 335
@@ -326,9 +346,9 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
326 static const char conv_words[] ALIGN1 = 346 static const char conv_words[] ALIGN1 =
327 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; 347 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
328 static const char iflag_words[] ALIGN1 = 348 static const char iflag_words[] ALIGN1 =
329 "skip_bytes\0""count_bytes\0""fullblock\0""direct\0"; 349 "skip_bytes\0""count_bytes\0""fullblock\0"IF_PLATFORM_POSIX("direct\0");
330 static const char oflag_words[] ALIGN1 = 350 static const char oflag_words[] ALIGN1 =
331 "seek_bytes\0append\0""direct\0"; 351 "seek_bytes\0append\0"IF_PLATFORM_POSIX("direct\0");
332#endif 352#endif
333#if ENABLE_FEATURE_DD_STATUS 353#if ENABLE_FEATURE_DD_STATUS
334 static const char status_words[] ALIGN1 = 354 static const char status_words[] ALIGN1 =
@@ -429,11 +449,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
429#if ENABLE_FEATURE_DD_IBS_OBS 449#if ENABLE_FEATURE_DD_IBS_OBS
430 if (what == OP_ibs) { 450 if (what == OP_ibs) {
431 /* Must fit into positive ssize_t */ 451 /* Must fit into positive ssize_t */
432 ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 452 ibs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
433 /*continue;*/ 453 /*continue;*/
434 } 454 }
435 if (what == OP_obs) { 455 if (what == OP_obs) {
436 obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 456 obs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
437 /*continue;*/ 457 /*continue;*/
438 } 458 }
439 if (what == OP_conv) { 459 if (what == OP_conv) {
@@ -450,7 +470,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
450 } 470 }
451#endif 471#endif
452 if (what == OP_bs) { 472 if (what == OP_bs) {
453 ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); 473 ibs = xatoul_range_sfx(val, 1, ULONG_MAX/2, cwbkMG_suffixes);
454 obs = ibs; 474 obs = ibs;
455 /*continue;*/ 475 /*continue;*/
456 } 476 }
@@ -515,7 +535,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
515# endif 535# endif
516 } 536 }
517#endif 537#endif
518 xmove_fd(xopen(infile, iflag), ifd); 538 xmove_fd(MINGW_SPECIAL(xopen)(infile, iflag), ifd);
539#if ENABLE_PLATFORM_MINGW32
540 update_special_fd(get_dev_type(infile), ifd);
541#endif
519 } else { 542 } else {
520 infile = bb_msg_standard_input; 543 infile = bb_msg_standard_input;
521 } 544 }
@@ -537,6 +560,27 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
537#endif 560#endif
538 xmove_fd(xopen(outfile, oflag), ofd); 561 xmove_fd(xopen(outfile, oflag), ofd);
539 562
563#if ENABLE_PLATFORM_MINGW32
564 {
565 off_t len = (off_t)seek * ((G.flags & FLAG_SEEK_BYTES) ? 1 : obs);
566 struct stat st;
567 int ret = fstat(ofd, &st);
568
569 if (ret == 0 && !(G.flags & FLAG_APPEND) && len > st.st_size)
570 make_sparse(ofd, st.st_size, len);
571
572 if (seek && !(G.flags & FLAG_NOTRUNC)) {
573 if (ftruncate(ofd, len) < 0) {
574 if (ret < 0
575 || S_ISREG(st.st_mode)
576 || S_ISDIR(st.st_mode)
577 ) {
578 goto die_outfile;
579 }
580 }
581 }
582 }
583#else
540 if (seek && !(G.flags & FLAG_NOTRUNC)) { 584 if (seek && !(G.flags & FLAG_NOTRUNC)) {
541 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs; 585 size_t blocksz = (G.flags & FLAG_SEEK_BYTES) ? 1 : obs;
542 if (ftruncate(ofd, seek * blocksz) < 0) { 586 if (ftruncate(ofd, seek * blocksz) < 0) {
@@ -550,6 +594,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
550 } 594 }
551 } 595 }
552 } 596 }
597#endif
553 } else { 598 } else {
554 outfile = bb_msg_standard_output; 599 outfile = bb_msg_standard_output;
555 } 600 }