By the way, behold the original (from UNIX Version 7) stdio package [0]:
fread(ptr, size, count, iop)
unsigned size, count;
register char *ptr;
register FILE *iop;
{
register c;
unsigned ndone, s;
ndone = 0;
if (size)
for (; ndone<count; ndone++) {
s = size;
do {
if ((c = getc(iop)) >= 0)
*ptr++ = c;
else
return(ndone);
} while (--s);
}
return(ndone);
}
Thankfully, the definition of getc() [1] is indeed
#define getc(p) (--(p)->_cnt>=0? *(p)->_ptr++&0377:_filbuf(p))
Interestingly enough, because there is no explicit multiplication, this loop properly works on systems with e.g. 16-bit unsigned int but 32-bit pointers (and overflows just the same on systems where ints and pointers are the same size).
[0] https://github.com/v7unix/v7unix/blob/master/v7/usr/src/libc...
[1] https://github.com/v7unix/v7unix/blob/master/v7/usr/include/...