[PATCH v2] dd: Error out when unable to write entire read block

Ari Sundholm ari at tuxera.com
Tue Jan 9 23:22:07 UTC 2018


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 <ari at tuxera.com>
---
 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



More information about the busybox mailing list