1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2002-09-11 01:09:04 +00:00
parent a82da9463f
commit f34534c52a
2 changed files with 107 additions and 21 deletions

View file

@ -1,3 +1,24 @@
Wed Sep 11 09:59:46 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* 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 <usa@ruby-lang.org> Wed Sep 11 09:29:24 2002 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/Makefile.sub (ext): make directory `ext' on compile dir. * win32/Makefile.sub (ext): make directory `ext' on compile dir.

99
io.c
View file

@ -261,6 +261,26 @@ io_fflush(f, fptr)
fptr->mode &= ~FMODE_WBUF; 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 */ /* writing functions */
static VALUE static VALUE
io_write(io, str) io_write(io, str)
@ -268,7 +288,8 @@ io_write(io, str)
{ {
OpenFile *fptr; OpenFile *fptr;
FILE *f; FILE *f;
long n; long n, r;
register char *ptr;
rb_secure(4); rb_secure(4);
if (TYPE(str) != T_STRING) if (TYPE(str) != T_STRING)
@ -284,23 +305,40 @@ io_write(io, str)
rb_io_check_writable(fptr); rb_io_check_writable(fptr);
f = GetWriteFile(fptr); f = GetWriteFile(fptr);
#ifdef __human68k__ ptr = RSTRING(str)->ptr;
{
register char *ptr = RSTRING(str)->ptr;
n = RSTRING(str)->len; n = RSTRING(str)->len;
while (--n >= 0) do {
if (fputc(*ptr++, f) == EOF) #ifdef __human68k__
if (fputc(*ptr++, f) == EOF) {
if (ferror(f)) rb_sys_fail(fptr->path);
break; break;
n = ptr - RSTRING(str)->ptr;
} }
if (n != RSTRING(str)->len && ferror(f)) --n;
rb_sys_fail(fptr->path);
#else #else
n = fwrite(RSTRING(str)->ptr, 1, RSTRING(str)->len, f); r = fwrite(ptr, 1, n, f);
if (n != RSTRING(str)->len && ferror(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); rb_sys_fail(fptr->path);
} }
#endif #endif
} while (n > 0);
n = ptr - RSTRING(str)->ptr;
if (fptr->mode & FMODE_SYNC) { if (fptr->mode & FMODE_SYNC) {
io_fflush(f, fptr); io_fflush(f, fptr);
} }
@ -544,6 +582,30 @@ rb_io_to_io(io)
} }
/* reading functions */ /* 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 long
rb_io_fread(ptr, len, f) rb_io_fread(ptr, len, f)
@ -585,11 +647,13 @@ rb_io_fread(ptr, len, f)
if (ferror(f)) { if (ferror(f)) {
switch (errno) { switch (errno) {
case EINTR: case EINTR:
clearerr(f);
continue; continue;
case EAGAIN: case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK: case EWOULDBLOCK:
#endif #endif
clearerr(f);
return len - n; return len - n;
} }
return 0; return 0;
@ -654,6 +718,7 @@ read_all(fptr, siz)
n = rb_io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr->f); n = rb_io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr->f);
if (pos > 0 && n == 0 && bytes == 0) { if (pos > 0 && n == 0 && bytes == 0) {
if (feof(fptr->f)) return Qnil; if (feof(fptr->f)) return Qnil;
if (!ferror(fptr->f)) return rb_str_new(0, 0);
rb_sys_fail(fptr->path); rb_sys_fail(fptr->path);
} }
bytes += n; bytes += n;
@ -765,8 +830,8 @@ appendline(fptr, delim, strp)
TRAP_END; TRAP_END;
if (c == EOF) { if (c == EOF) {
if (ferror(f)) { if (ferror(f)) {
if (errno == EINTR) continue; io_read_retryable(f, fptr->path);
rb_sys_fail(fptr->path); continue;
} }
return c; return c;
} }
@ -1078,8 +1143,8 @@ rb_io_each_byte(io)
TRAP_END; TRAP_END;
if (c == EOF) { if (c == EOF) {
if (ferror(f)) { if (ferror(f)) {
if (errno == EINTR) continue; io_read_retryable(f, fptr->path);
rb_sys_fail(fptr->path); continue;
} }
break; break;
} }
@ -1109,8 +1174,8 @@ rb_io_getc(io)
if (c == EOF) { if (c == EOF) {
if (ferror(f)) { if (ferror(f)) {
if (errno == EINTR) goto retry; io_read_retryable(f, fptr->path);
rb_sys_fail(fptr->path); goto retry;
} }
return Qnil; return Qnil;
} }