Subject: bug#7362: dd strangeness

From: Paul Eggert <[email-masked]>
Date: Tue, 01 Mar 2011 11:30:12 -0800

On 03/01/2011 09:45 AM, Paul Eggert wrote:
> By the way, the relationship between fullblock and ibs=N obs=N is
> a curious one, one that I don't fully understand.  If you have
> ibs=N obs=N, why would you need fullblock?  This should probably
> be documented (preferably by someone who understands it :-).

In looking into this some more, I did find one difference
(or at least, something that *should* be a difference).

POSIX says that when an input record has
an odd size, conv=swab should output the last byte as-is.
If dd obeyed POSIX, ibs=100 obs=100 conv=swab would differ
from bs=100 iflag=fullblock conv=swab in that the latter would
swap every pair of input bytes, regardless of how many bytes
are returned by individual 'read' system calls, whereas the
former would not swap the last byte of each input record that
has an odd size.

Except -- GNU dd doesn't conform to POSIX here!  It swaps
bytes in the ibs=100 obs=100 conv=swab case, even when an
input record has an odd number of bytes and POSIX says the
last byte shouldn't be swapped.

For example:

(echo ab; sleep 1; echo cd) | dd ibs=100 conv=swab 2>/dev/null

POSIX says the output should be:

ba
dc

(and Solaris dd agrees with POSIX here).  But GNU dd outputs:

bac

(with a blank line at the end).

I suspect that this incompatibility was put in before the fullblock
flag was added, because of the need to be able to swap bytes reliably.
However, this need is better served by the fullblock option, so we
should remove the incompatibility.