diff options
Diffstat (limited to 'coreutils/dd.c')
-rw-r--r-- | coreutils/dd.c | 61 |
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 | ||
308 | static void *alloc_buf(size_t size) | 326 | static 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 | } |