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