io.c:804
static VALUE
io_read(argc, argv, io)
    int argc;
    VALUE *argv;
    VALUE io;
{
    OpenFile *fptr;
    long n, len;
    VALUE length, str;

    rb_scan_args(argc, argv, "02", &length, &str);

    GetOpenFile(io, fptr);
    rb_io_check_readable(fptr);
    if (NIL_P(length)) {
	return read_all(fptr, remain_size(fptr), str);
    }

    len = NUM2LONG(length);
    if (len < 0) {
	rb_raise(rb_eArgError, "negative length %ld given", len);
    }

    if (feof(fptr->f)) return Qnil;
    if (NIL_P(str)) {
	str = rb_str_new(0, len);
    }
    else {
	StringValue(str);
	rb_str_modify(str);
	rb_str_resize(str,len);
    }
    if (len == 0) return str;

    READ_CHECK(fptr->f);
    n = rb_io_fread(RSTRING(str)->ptr, len, fptr->f);
    if (n == 0) {
	rb_str_resize(str,0);
	if (feof(fptr->f)) return Qnil;
	if (len > 0) rb_sys_fail(fptr->path);
    }
    RSTRING(str)->len = n;
    RSTRING(str)->ptr[n] = '\0';
    OBJ_TAINT(str);

    return str;
}
