* Maxim Sobolev, 2016-02-10 : > Looking at the code in question I don't see how could it have worked. Look > at the following piece of code in your diff for example: > > + if (force && cnt == 0) { > + pending -= last_sp; > + assert(outp == out.db); > + memset(outp, 0, cnt); > + } > > When the branch is taken, cnt is 0, so at the very least memset(x, y, 0) is > NOP. Later on, write(2) is conditional on cnt != 0, so that it's never > taken. As a result, lseek is the last operation the file sees.
Correct :-( In the context of the current logic, I think the simple fix is: Index: dd.c =================================================================== --- dd.c (révision 265593) +++ dd.c (copie de travail) @@ -470,6 +470,7 @@ */ if (force && cnt == 0) { pending -= last_sp; + cnt += last_sp; assert(outp == out.db); memset(outp, 0, cnt); } > Also, for what it's worth, you can use ftruncate(2) instead of write() for > regular sparse files to ensure correct size. That would write just as much > data as needed to the end. I've made a quick and dirty patch, that seems to > be working better than current code at least: > > http://sobomax.sippysoft.com/dd.diff > > Please fix. Leveraging ftruncate certainly seems attractive, if the destination is a regular file. I'll look into this option. Thanks! Thomas.
pgpGomdFv7CHJ.pgp
Description: PGP signature