Code: Select all
size_t fread(void *buf, size_t r, size_t n, FILE *stream)
{
size_t ret;
switch(stream->type) {
case STD_IOBUF_TYPE_NONE:
case STD_IOBUF_TYPE_GS:
case STD_IOBUF_TYPE_SIO:
case STD_IOBUF_TYPE_STDOUTHOST:
/* cannot read from stdout or stderr. */
ret = 0;
break;
default:
/* attempt to read from the stream file. */
if (stream->has_putback) {
buf[0] = stream->putback;
buf++;
stream->has_putback = 0;
/* subtract 1 from r * n to avoid buffer overflow */
ret = (_ps2sdk_read(stream->fd, buf, (int)((r * n) -1 ))) / (int)r);
} else {
ret = (_ps2sdk_read(stream->fd, buf, (int)(r * n)) / (int)r);
}
}
return (ret);
}
fread() will return partial records if your record size is >1. That seems odd to me, but that is the current behavior so I guess we should just leave it alone for the moment.
e.g.
If I ask to read 10 records of size 4, and fread() finds 38 bytes, I would expect it to return 9 records of size 4 (36 bytes), not 38 bytes which is 9 records plus a half record. The return value of fread() will be 9 because it is forced to an int, so it will lie about how much data it read. Then if you fread() again you will have mis-aligned data because you have already read 1/2 of the record, but you didn't know that because the function lied.
I'm not sure what the behavior of fread() is in a standard implementation, though... I haven't used C extensively in a long time. This may be just a caveat.
It should still probably subtract the 1 from (r * n)... Either way it won't fix the above problem.