zlib's gzseek return gabbage and fails intermittently under wine.
Hin-Tak Leung
htl10 at users.sourceforge.net
Sun Apr 14 17:50:09 CDT 2013
--- On Sun, 14/4/13, Vincent Povirk <madewokherd at gmail.com> wrote:
> Well, here's a simple thing you can
> check: Does your zlib dll link to
> _lseek or _lseeki64? The first one uses a 32-bit offset.
> Wine's
> implementation (http://source.winehq.org/source/dlls/msvcrt/file.c#L1090)
> expands that to 64-bit and later truncates the file offset
> to 32-bit.
> For a file larger than 2 GB, that could account for the
> large negative
> value you're seeing.
>
> And since this would only matter in cases where zlib uses
> lseek (the
> first time through I guess it wouldn't, as it has to read
> the whole
> everything up to the offset you give at least once) and is
> at least 2
> GB into the file, that might also explain why it doesn't
> fail
> initially.
>
> But without really digging into the zlib code, all I can do
> it speculate.
>
> I should probably also check coapp's build of zlib
> sometime.
It is not a dll - as you suggested and I already wrote, due to past experience of other's packaging of slightly outdated, it is being built against a private *source* copy of the latest zlib.
Also the bogus offset is not large negative but large (larger than 2^32) positive.
Here is an example of the debug output under wine:
---------------
set_filepos failed at 34307 returning 134127533721091
Re-opening to re-try
Retry successful
set_filepos failed at 96919 returning 146686018157207
Re-opening to re-try
Retry successful
set_filepos failed at 128254 returning 12103217968382
Re-opening to re-try
Retry successful
...
---------------
This is generated by this code snipplet which is called inside a loop, all wrapped in the c++ class:
---------------
off_t offset = gzseek(gzvcf_in, filepos, SEEK_SET);
if (offset != filepos) { //implicitly converted to off_t by template streamoff()
LOG.printLOG("set_filepos failed at " + LOG.streampos2str(filepos)
+ " returning " + LOG.off_t2str(offset) + "\n");
LOG.printLOG("Re-opening to re-try\n");
close(); open();
off_t offset1 = gzseek(gzvcf_in, filepos, SEEK_SET);
if (offset1 == filepos)
LOG.printLOG("Retry successful\n");
else
LOG.error("Retry failed\n"); // this also aborts
}
-------------------
This code runs silently on linux i.e. the "if (offset != filepos)" condition is not triggered.
More information about the wine-devel
mailing list