From f34534c52afc423e3b48b54c1b127c26098b59de Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 11 Sep 2002 01:09:04 +0000 Subject: retry on EINTR, ERESTART and EWOULDBLOCK. [ruby-dev:17855], [ruby-dev:17878], [ruby-core:00444] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2841 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 21 ++++++++++++ io.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 107 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4185dcf02..b0ce1d3f50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Wed Sep 11 09:59:46 2002 Nobuyoshi Nakada + + * io.c (rb_io_wait_readable): added. + + * io.c (rb_io_wait_writable): added. + + * io.c (io_read_retryable): added. + + * io.c (io_write): retry on EINTR, ERESTART and EWOULDBLOCK. + [ruby-dev:17855], [ruby-dev:17878], [ruby-core:00444] + + * io.c (rb_io_fread): ditto. + + * io.c (read_all): ditto. + + * io.c (appendline): ditto. + + * io.c (rb_io_each_byte): ditto. + + * io.c (rb_io_getc): ditto. + Wed Sep 11 09:29:24 2002 NAKAMURA Usaku * win32/Makefile.sub (ext): make directory `ext' on compile dir. diff --git a/io.c b/io.c index 90338e6f2a..e6c873604d 100644 --- a/io.c +++ b/io.c @@ -261,6 +261,26 @@ io_fflush(f, fptr) fptr->mode &= ~FMODE_WBUF; } +void +rb_io_wait_readable(f) + int f; +{ + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(f, &rfds); + rb_thread_select(f + 1, &rfds, NULL, NULL, NULL); +} + +void +rb_io_wait_writable(f) + int f; +{ + fd_set wfds; + FD_ZERO(&wfds); + FD_SET(f, &wfds); + rb_thread_select(f + 1, NULL, &wfds, NULL, NULL); +} + /* writing functions */ static VALUE io_write(io, str) @@ -268,7 +288,8 @@ io_write(io, str) { OpenFile *fptr; FILE *f; - long n; + long n, r; + register char *ptr; rb_secure(4); if (TYPE(str) != T_STRING) @@ -284,23 +305,40 @@ io_write(io, str) rb_io_check_writable(fptr); f = GetWriteFile(fptr); + ptr = RSTRING(str)->ptr; + n = RSTRING(str)->len; + do { #ifdef __human68k__ - { - register char *ptr = RSTRING(str)->ptr; - n = RSTRING(str)->len; - while (--n >= 0) - if (fputc(*ptr++, f) == EOF) - break; - n = ptr - RSTRING(str)->ptr; - } - if (n != RSTRING(str)->len && ferror(f)) - rb_sys_fail(fptr->path); + if (fputc(*ptr++, f) == EOF) { + if (ferror(f)) rb_sys_fail(fptr->path); + break; + } + --n; #else - n = fwrite(RSTRING(str)->ptr, 1, RSTRING(str)->len, f); - if (n != RSTRING(str)->len && ferror(f)) { - rb_sys_fail(fptr->path); - } + r = fwrite(ptr, 1, n, f); + ptr += r; + n -= r; + 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 + clearerr(f); + rb_io_wait_writable(fileno(f)); + continue; + } + rb_sys_fail(fptr->path); + } +#endif + } while (n > 0); + n = ptr - RSTRING(str)->ptr; if (fptr->mode & FMODE_SYNC) { io_fflush(f, fptr); } @@ -544,6 +582,30 @@ rb_io_to_io(io) } /* reading functions */ +static void +io_read_retryable(f, path) + FILE *f; + const char *path; +{ + switch (errno) { + case EINTR: +#if defined(ERESTART) + case ERESTART: +#endif + clearerr(f); + break; + case EAGAIN: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + clearerr(f); + rb_io_wait_readable(fileno(f)); + break; + default: + rb_sys_fail(path); + break; + } +} long rb_io_fread(ptr, len, f) @@ -585,11 +647,13 @@ rb_io_fread(ptr, len, f) if (ferror(f)) { switch (errno) { case EINTR: + clearerr(f); continue; case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: #endif + clearerr(f); return len - n; } return 0; @@ -654,6 +718,7 @@ read_all(fptr, siz) n = rb_io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr->f); if (pos > 0 && n == 0 && bytes == 0) { if (feof(fptr->f)) return Qnil; + if (!ferror(fptr->f)) return rb_str_new(0, 0); rb_sys_fail(fptr->path); } bytes += n; @@ -765,8 +830,8 @@ appendline(fptr, delim, strp) TRAP_END; if (c == EOF) { if (ferror(f)) { - if (errno == EINTR) continue; - rb_sys_fail(fptr->path); + io_read_retryable(f, fptr->path); + continue; } return c; } @@ -1078,8 +1143,8 @@ rb_io_each_byte(io) TRAP_END; if (c == EOF) { if (ferror(f)) { - if (errno == EINTR) continue; - rb_sys_fail(fptr->path); + io_read_retryable(f, fptr->path); + continue; } break; } @@ -1109,8 +1174,8 @@ rb_io_getc(io) if (c == EOF) { if (ferror(f)) { - if (errno == EINTR) goto retry; - rb_sys_fail(fptr->path); + io_read_retryable(f, fptr->path); + goto retry; } return Qnil; } -- cgit v1.2.3