On 01/03/11 19:30, Paul Eggert wrote: > 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.
Oh good spot. One can use an odd block size to test directly: [solaris-10]$ echo abcde | dd bs=3 conv=swab 2>/dev/null baced [solaris-10]$ printf "abcd\n" | dd bs=3 conv=swab 2>/dev/null bac [solaris-10]$ printf "abcd" | dd bs=3 conv=swab 2>/dev/null bacSegmentation Fault (core dumped) So solaris is not being POSIX compliant either :) Seriously though, changing to output the trailing byte directly might break existing scripts that are swapping from a pipe. I suppose we could warn to use fullblock if (!input_seekable && C_SWAB && !ibs%2 && nread%2) though that would warn for your example above. So I'm not sure how to proceed here. cheers, Pádraig.
