From 5afd63a631f49112ac305ea1532dd226e9c39d12 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 10 Jan 2018 10:58:55 +0100 Subject: dd: exit with 1 if last write was incomplete $ busybox dd if=/dev/zero of=/dev/loop0 bs=100M count=8; echo $? 8+0 records in 7+1 records out 805220352 bytes (767.9MB) copied, 0.464010 seconds, 1.6GB/s 1 <=========== FIXED function old new delta write_and_stats 96 97 +1 Signed-off-by: Denys Vlasenko --- coreutils/dd.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'coreutils/dd.c') diff --git a/coreutils/dd.c b/coreutils/dd.c index d302f35d3..9d173cc13 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -195,14 +195,16 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs, ssize_t n = full_write_or_warn(buf, len, filename); if (n < 0) return 1; - if ((size_t)n == obs) - G.out_full++; - else if (n) /* > 0 */ - G.out_part++; #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE G.total_bytes += n; #endif - return 0; + if ((size_t)n == obs) { + G.out_full++; + return 0; + } + if (n) /* > 0 */ + G.out_part++; + return 1; } #if ENABLE_LFS -- cgit v1.2.3-55-g6feb From 2c876774a90ddb7478937ead096937f64e6bd7ec Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 10 Jan 2018 11:04:09 +0100 Subject: dd: fixed partial count logic $ busybox dd if=/dev/zero of=/dev/loop0 bs=100M count=8; echo $? 8+0 records in 7+0 records out <=========== FIXED, was 7+1 805220352 bytes (767.9MB) copied, 0.464010 seconds, 1.6GB/s 1 function old new delta write_and_stats 97 99 +2 Signed-off-by: Denys Vlasenko --- coreutils/dd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'coreutils/dd.c') diff --git a/coreutils/dd.c b/coreutils/dd.c index 9d173cc13..38b2a6aa1 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -202,8 +202,10 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs, G.out_full++; return 0; } - if (n) /* > 0 */ + if ((size_t)n == len) { G.out_part++; + return 0; + } return 1; } -- cgit v1.2.3-55-g6feb From 77a6678c427db5ea15d6d0005a579f441277df06 Mon Sep 17 00:00:00 2001 From: Nicholas Clark Date: Thu, 25 Jan 2018 19:00:19 +0100 Subject: dd: add 'fullblock' iflag Adds a fullblock iflag for improved compatibility with GNU dd. The new iflag can be used to ensure that dd calls retrieve the expected amount of data when reading from pipes or unusual filesystems. function old new delta packed_usage 32249 32334 +85 dd_main 1582 1632 +50 static.iflag_words 12 22 +10 ------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 145/0) Total: 145 bytes Signed-off-by: Nicholas Clark Signed-off-by: Denys Vlasenko --- coreutils/dd.c | 33 +++++++++++++++++++++++---------- docs/posix_conformance.txt | 5 +++-- 2 files changed, 26 insertions(+), 12 deletions(-) (limited to 'coreutils/dd.c') diff --git a/coreutils/dd.c b/coreutils/dd.c index 38b2a6aa1..0f130bcad 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -37,7 +37,7 @@ //config: elapsed time and speed. //config: //config:config FEATURE_DD_IBS_OBS -//config: bool "Enable ibs, obs and conv options" +//config: bool "Enable ibs, obs, iflag and conv options" //config: default y //config: depends on DD //config: help @@ -57,7 +57,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] [iflag=skip_bytes]") +//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes|fullblock]") //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" @@ -79,6 +79,7 @@ //usage: "\n conv=fsync Physically write data out before finishing" //usage: "\n conv=swab Swap every pair of bytes" //usage: "\n iflag=skip_bytes skip=N is in bytes" +//usage: "\n iflag=fullblock Read full blocks" //usage: ) //usage: IF_FEATURE_DD_STATUS( //usage: "\n status=noxfer Suppress rate output" @@ -130,11 +131,12 @@ enum { /* start of input flags */ FLAG_IFLAG_SHIFT = 5, FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, + FLAG_FULLBLOCK = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS, /* end of input flags */ - FLAG_TWOBUFS = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS, - FLAG_COUNT = 1 << 7, - FLAG_STATUS_NONE = 1 << 8, - FLAG_STATUS_NOXFER = 1 << 9, + FLAG_TWOBUFS = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS, + FLAG_COUNT = 1 << 8, + FLAG_STATUS_NONE = 1 << 9, + FLAG_STATUS_NOXFER = 1 << 10, }; static void dd_output_status(int UNUSED_PARAM cur_signal) @@ -255,7 +257,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) static const char conv_words[] ALIGN1 = "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; static const char iflag_words[] ALIGN1 = - "skip_bytes\0"; + "skip_bytes\0""fullblock\0"; #endif #if ENABLE_FEATURE_DD_STATUS static const char status_words[] ALIGN1 = @@ -294,6 +296,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) /* Partially implemented: */ //swab swap every pair of input bytes: will abort on non-even reads OP_iflag_skip_bytes, + OP_iflag_fullblock, #endif }; smallint exitcode = EXIT_FAILURE; @@ -454,7 +457,13 @@ int dd_main(int argc UNUSED_PARAM, char **argv) size_t blocksz = (G.flags & FLAG_SKIP_BYTES) ? 1 : ibs; if (lseek(ifd, skip * blocksz, SEEK_CUR) < 0) { do { - ssize_t n = safe_read(ifd, ibuf, blocksz); + ssize_t n; +#if ENABLE_FEATURE_DD_IBS_OBS + if (G.flags & FLAG_FULLBLOCK) + n = full_read(ifd, ibuf, blocksz); + else +#endif + n = safe_read(ifd, ibuf, blocksz); if (n < 0) goto die_infile; if (n == 0) @@ -469,8 +478,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) while (!(G.flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { ssize_t n; - - n = safe_read(ifd, ibuf, ibs); +#if ENABLE_FEATURE_DD_IBS_OBS + if (G.flags & FLAG_FULLBLOCK) + n = full_read(ifd, ibuf, ibs); + else +#endif + n = safe_read(ifd, ibuf, ibs); if (n == 0) break; if (n < 0) { diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt index 8b9112020..cdf89b744 100644 --- a/docs/posix_conformance.txt +++ b/docs/posix_conformance.txt @@ -178,9 +178,10 @@ dd POSIX options: conv=noerror | yes | | conv=notrunc | yes | | conv=sync | yes | | +dd compatibility options: + conv=fsync | yes | | iflag=skip_bytes| yes | | -dd Busybox specific options: - conv=fsync + iflag=fullblock | yes | | df POSIX options option | exists | compliant | remarks -- cgit v1.2.3-55-g6feb