summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'io.c')
-rw-r--r--io.c72
1 files changed, 34 insertions, 38 deletions
diff --git a/io.c b/io.c
index d5701dcb8ab..f3fd3153236 100644
--- a/io.c
+++ b/io.c
@@ -426,6 +426,36 @@ rb_io_to_io(io)
/* reading functions */
+static size_t
+io_fread(ptr, len, f)
+ char *ptr;
+ size_t len;
+ FILE *f;
+{
+ size_t n = len;
+ int c;
+
+ while (n--) {
+ if (!READ_DATA_PENDING(f)) {
+ rb_thread_wait_fd(fileno(f));
+ }
+ TRAP_BEG;
+ c = getc(f);
+ TRAP_END;
+ if (c == EOF) {
+ if (ferror(f)) {
+ if (errno == EINTR) continue;
+ rb_sys_fail(0);
+ }
+ *ptr = '\0';
+ break;
+ }
+ *ptr++ = c;
+ }
+
+ return len - n - 1;
+}
+
#ifndef S_ISREG
# define S_ISREG(m) ((m & S_IFMT) == S_IFREG)
#endif
@@ -464,12 +494,10 @@ read_all(port)
}
}
}
- str = rb_str_new(0, siz);
+ str = rb_tainted_str_new(0, siz);
+ READ_CHECK(fptr->f);
for (;;) {
- READ_CHECK(fptr->f);
- TRAP_BEG;
- n = fread(RSTRING(str)->ptr+bytes, 1, siz-bytes, fptr->f);
- TRAP_END;
+ n = io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr->f);
if (n == 0 && bytes == 0) {
if (feof(fptr->f)) return Qnil;
rb_sys_fail(fptr->path);
@@ -481,41 +509,10 @@ read_all(port)
}
if (bytes == 0) return rb_str_new(0,0);
if (bytes != siz) rb_str_resize(str, bytes);
- OBJ_TAINT(str);
return str;
}
-static size_t
-io_fread(ptr, len, f)
- char *ptr;
- size_t len;
- FILE *f;
-{
- size_t n = len;
- int c;
-
- while (n--) {
- if (!READ_DATA_PENDING(f)) {
- rb_thread_wait_fd(fileno(f));
- }
- TRAP_BEG;
- c = getc(f);
- TRAP_END;
- if (c == EOF) {
- if (ferror(f)) {
- if (errno == EINTR) continue;
- rb_sys_fail(0);
- }
- *ptr = '\0';
- break;
- }
- *ptr++ = c;
- }
-
- return len - n - 1;
-}
-
static VALUE
io_read(argc, argv, io)
int argc;
@@ -1795,6 +1792,7 @@ io_reopen(io, nfile)
mode = rb_io_mode_string(fptr);
fd = fileno(fptr->f);
if (fd < 3) {
+ clearerr(fptr->f);
/* need to keep stdio */
if (dup2(fileno(orig->f), fd) < 0)
rb_sys_fail(orig->path);
@@ -3175,8 +3173,6 @@ argf_eof()
{
if (init_p == 0 && !next_argv())
return Qtrue;
- if (next_p == -1)
- return Qtrue;
if (TYPE(current_file) != T_FILE) {
return argf_forward();
}