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

Stefan Seyfried stefan.seyfried at googlemail.com
Sun Jan 14 10:57:17 UTC 2018


Am 10.01.2018 um 00:22 schrieb Ari Sundholm:
> 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) */

even here, G.out_part should be increased, at least if (n > 0), maybe
like this:

        if ((size_t)n == obs)
                G.out_full++;
        else {
                G.out_part++;
                /* doesn't work when len == 0! */
                if ((size_t)n != len)
                        return 1;
        }
        return 0;

> +		return 1;
>  	return 0;
>  }-- 
Stefan Seyfried

"For a successful technology, reality must take precedence over
 public relations, for nature cannot be fooled." -- Richard Feynman


More information about the busybox mailing list