lseek is valid on e.g. /dev/hda and people
would not expect dd to null their data till it reached the desired
offset.

True. I guess the algorithm should be to use lseek if possible, and
to write nulls otherwise. Then ftruncate if possible.

I agree. I also think that ftruncate should happen regardless of the
presence of of=. This would allow cases like `true | dd seek=1 >> file'

to work properly.

Perhaps dd should output null bytes only on FIFOs ?

I'd say it should output nulls if lseek fails for any reason.

Hmm, so all we need is some code in skip() to fall back to iwrite for
STDOUT_FILENO.

On a relative matter, what should dd do in the following case:
$ echo -n AB > f
$ echo -n ab | dd bs=1 seek=1 >> f
What should the contents of `f' be ?

Just "ABab". That's a tricky one, since the ">>f" means that stdout
is in append mode, which means all writes are appended to the end of
the file regardless of the current seek position. So the "seek=1" is
ineffective.