Busybox dd has a difference in behavior compared to coreutils dd
in the case where the block count has been given and the last block
can only partially be written (usually due to ENOSPC):

        $ dd if=/dev/zero of=foo bs=100M count=8; echo $?; rm foo
        dd: error writing 'foo': No space left on device
        8+0 records in
        7+0 records out
        805220352 bytes (805 MB, 768 MiB) copied, 0.405782 s, 2.0 GB/s
        1
        $ busybox dd if=/dev/zero of=foo bs=100M count=8; echo $?; rm foo
        8+0 records in
        7+1 records out
        0
        $ df -h .
        Filesystem      Size  Used Avail Use% Mounted on
        tmpfs           768M  8.0K  768M   1% [redacted]
        $

This breaks scripts which rely on busybox dd giving an exit value
indicating failure when writing data fails.

The solution is to error out when the block that was just read (be
it full or partial) couldn't be written out in full, just as coreutils
dd does.

Signed-off-by: Ari Sundholm <[email protected]>
---
 coreutils/dd.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/coreutils/dd.c b/coreutils/dd.c
index d302f35..6221ebe 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -195,13 +195,15 @@ 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
+       if ((size_t)n == obs)
+               G.out_full++;
+       else if ((size_t)n == len)
+               G.out_part++;
+       else /* if ((size_t)n != len) */
+               return 1;
        return 0;
 }
 
-- 
2.7.4

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to