summaryrefslogtreecommitdiffstats
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
commitb69bc5325a83c189cdcd76b1c2d8dd064b29c13b (patch)
tree576be89cd28851127c4334139af024f500ac20be /io.c
parent589a9ccc050c8ccee7eace420989070547d8dab6 (diff)
downloadruby-b69bc5325a83c189cdcd76b1c2d8dd064b29c13b.tar.gz
ruby-b69bc5325a83c189cdcd76b1c2d8dd064b29c13b.tar.xz
ruby-b69bc5325a83c189cdcd76b1c2d8dd064b29c13b.zip
* 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: http://svn.ruby-lang.org/repos/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 d5ffa0cf6..ced6a7aed 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");
}