pawn
pawn copied to clipboard
`lseek` `SEEK_SET` fails on Windows
No idea why, but the function call returns 0
(which is correct), yet future writes continue from the old location not the new one. I had to change fseek
to:
return fseek((FILE *)params[1],params[2],whence);
And flength
to:
int fn=fileno((FILE*)params[1]);
c=lseek(fn,0,SEEK_CUR); /* save the current position */
l=lseek(fn,0,SEEK_END); /* return the file position at its end */
fseek((FILE *)params[1],c,SEEK_SET); /* restore the file pointer */
The latter uses a mix of lseek
and fseek
because all of one or the other failed in different ways.
Maybe this happens on a file bigger than 2 GB? windows has _lseeki64
for big files
The file I tested it with was 13 bytes:
bool:test_fseek()
{
fremove("fseek.ini");
new File:f = fopen("fseek.ini", io_write);
if (!f)
{
print("FAIL: File didn't open\n");
return false;
}
fwrite(f, "hello world");
fseek(f, 0, seek_start);
fwrite(f, "hi");
if (flength(f) != 11)
{
print("FAIL: `flength` != 11\n");
return false;
}
fwrite(f, "hello world");
if (flength(f) != 13)
{
print("FAIL: `flength` != 13\n");
return false;
}
fclose(f);
return true;
}
Reading through POSIX and various documentations there doesn't seem to be any guarantee of relations between a fd and a FILE. Additionally, the C standard allows FILE to store position information. So I think the code is just simply wrong and built on top of incorrect assumptions.