summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-06-11 14:54:23 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-06-11 14:54:23 +0000
commita999490fe3832b0706816890eccfe6699b4737aa (patch)
tree576be89cd28851127c4334139af024f500ac20be /io.c
parent2dc5f35a3a1baabeed4d13bfee1ee6b504d45cf9 (diff)
* io.c (io_fread): bypass buffered read if reading buffer is empty.
* io.c (remain_size): do not add extra one byte. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17098 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/io.c b/io.c
index d5ffa0cf6c..ced6a7aed7 100644
--- a/io.c
+++ b/io.c
@@ -1298,6 +1298,20 @@ io_fread(VALUE str, long offset, rb_io_t *fptr)
long n = len;
int c;
+ if (READ_DATA_PENDING(fptr) == 0) {
+ while (n > 0) {
+ c = rb_read_internal(fptr->fd, RSTRING_PTR(str)+offset, n);
+ if (c == 0) break;
+ if (c < 0) {
+ rb_sys_fail(fptr->path);
+ }
+ offset += c;
+ if ((n -= c) <= 0) break;
+ rb_thread_wait_fd(fptr->fd);
+ }
+ return len - n;
+ }
+
while (n > 0) {
c = read_buffered_data(RSTRING_PTR(str)+offset, n, fptr);
if (c > 0) {
@@ -1347,7 +1361,7 @@ remain_size(rb_io_t *fptr)
io_fflush(fptr);
pos = lseek(fptr->fd, 0, SEEK_CUR);
if (st.st_size >= pos && pos >= 0) {
- siz += st.st_size - pos + 1;
+ siz += st.st_size - pos;
if (siz > LONG_MAX) {
rb_raise(rb_eIOError, "file too big for single read");
}