io.c:668
long
rb_io_fread(ptr, len, f)
    char *ptr;
    long len;
    FILE *f;
{
    long n = len;
    int c;

    while (n > 0) {
#ifdef READ_DATA_PENDING_COUNT
	long i = READ_DATA_PENDING_COUNT(f);
	if (i <= 0) {
	    rb_thread_wait_fd(fileno(f));
	    i = READ_DATA_PENDING_COUNT(f);
	}
	if (i > 0) {
	    if (i > n) i = n;
	    TRAP_BEG;
	    c = fread(ptr, 1, i, f);
	    TRAP_END;
	    if (c < 0) goto eof;
	    ptr += c;
	    n -= c;
	    if (c < i) goto eof;
	    continue;
	}
#else
	if (!READ_DATA_PENDING(f)) {
	    rb_thread_wait_fd(fileno(f));
	}
#endif
	TRAP_BEG;
	c = getc(f);
	TRAP_END;
	if (c == EOF) {
	  eof:
	    if (ferror(f)) {
		switch (errno) {
		  case EINTR:
#if defined(ERESTART)
		  case ERESTART:
#endif
		    clearerr(f);
		    continue;
		  case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
		  case EWOULDBLOCK:
#endif
		    if (len - n >= 0) {
			clearerr(f);
			return len - n;
		    }
		}
		return 0;
	    }
	    *ptr = '\0';
	    break;
	}
	*ptr++ = c;
	n--;
    }
    return len - n;
}
