#include #include #include "fileutil.h" size_t fread(void *data, size_t membsize, size_t nmemb, FILE *fp) { size_t size; if(__builtin_umul_overflow(membsize, nmemb, &size)) { fp->error = 1; return 0; } if(!fp->buf) { ssize_t rc = __fp_read(fp, data, size); return (rc == EOF) ? 0 : rc; } __fp_buffer_mode_read(fp); size_t size_read = 0; while(size_read < size) { /* Take what's available in the buffer (may be 0, but only during the first iteration) */ size_t size_frag = fp->bufread - fp->bufpos; if(size_frag > size - size_read) size_frag = size - size_read; memcpy(data + size_read, fp->buf + fp->bufpos, size_frag); size_read += size_frag; fp->bufpos += size_frag; if(fp->bufpos >= fp->bufread) { fp->bufread = 0; fp->bufpos = 0; } if(size_read >= size) break; /* Get more data */ ssize_t rc = __fp_read(fp, fp->buf, fp->bufsize); if(rc <= 0) /* EOF or error */ break; fp->bufread = rc; } return size_read; }