diff --git a/ChangeLog b/ChangeLog index 41f7105dc5..1b060d7a3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Wed Oct 2 23:09:20 2002 Nobuyoshi Nakada + + * io.c (rb_io_wait_readable): handle retryable errors. + + * io.c (rb_io_wait_writable): ditto. + + * ext/socket/socket.c (bsock_send): ditto. + + * ext/socket/socket.c (s_recvfrom): ditto. + + * ext/socket/socket.c (s_accept): ditto. + + * ext/socket/socket.c (udp_send): ditto. + + * ext/socket/getaddrinfo.c (afdl): made private structures constant. + + * rubyio.h: prototype; rb_io_wait_readable(), rb_io_wait_writable(). + Wed Oct 2 13:03:58 2002 WATANABE Hirofumi * configure.in: set ac_cv_func_setitimer to "no" on Cygwin. diff --git a/ext/socket/getaddrinfo.c b/ext/socket/getaddrinfo.c index 0a6af3111f..06daa7cca2 100644 --- a/ext/socket/getaddrinfo.c +++ b/ext/socket/getaddrinfo.c @@ -105,7 +105,7 @@ struct sockinet { u_short si_port; }; -static struct afd { +static const struct afd { int a_af; int a_addrlen; int a_socklen; @@ -136,14 +136,14 @@ static struct afd { #define PTON_MAX 4 #endif -static int get_name __P((const char *, struct afd *, +static int get_name __P((const char *, const struct afd *, struct addrinfo **, char *, struct addrinfo *, int)); static int get_addr __P((const char *, int, struct addrinfo **, struct addrinfo *, int)); static int str_isnumber __P((const char *)); -static const char *ai_errlist[] = { +static const char *const ai_errlist[] = { "success.", "address family for hostname not supported.", /* EAI_ADDRFAMILY */ "temporary failure in name resolution.", /* EAI_AGAIN */ @@ -418,7 +418,7 @@ getaddrinfo(hostname, servname, hints, res) * non-passive socket -> localhost (127.0.0.1 or ::1) */ if (hostname == NULL) { - struct afd *afd; + const struct afd *afd; int s; for (afd = &afdl[0]; afd->a_af; afd++) { @@ -533,7 +533,7 @@ getaddrinfo(hostname, servname, hints, res) static int get_name(addr, afd, res, numaddr, pai, port0) const char *addr; - struct afd *afd; + const struct afd *afd; struct addrinfo **res; char *numaddr; struct addrinfo *pai; @@ -588,7 +588,7 @@ get_addr(hostname, af, res, pai, port0) struct addrinfo sentinel; struct hostent *hp; struct addrinfo *top, *cur; - struct afd *afd; + const struct afd *afd; int i, error = 0, h_error; char *ap; diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 1c671fdb63..0825e8d155 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -368,9 +368,9 @@ bsock_send(argc, argv, sock) GetOpenFile(sock, fptr); f = GetWriteFile(fptr); fd = fileno(f); - retry: rb_thread_fd_writable(fd); StringValue(mesg); + retry: if (!NIL_P(to)) { StringValue(to); n = sendto(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags), @@ -380,9 +380,7 @@ bsock_send(argc, argv, sock) n = send(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags)); } if (n < 0) { - switch (errno) { - case EINTR: - rb_thread_schedule(); + if (rb_io_wait_writable(fd)) { goto retry; } rb_sys_fail("send(2)"); @@ -438,9 +436,7 @@ s_recvfrom(sock, argc, argv, from) TRAP_END; if (slen < 0) { - switch (errno) { - case EINTR: - rb_thread_schedule(); + if (rb_io_wait_readable(fd)) { goto retry; } rb_sys_fail("recvfrom(2)"); @@ -1166,8 +1162,9 @@ s_accept(klass, fd, sockaddr, len) rb_gc(); retry = 1; goto retry; - case EINTR: - rb_thread_schedule(); + default: + if (!rb_io_wait_readable(fd)) break; + retry = 0; goto retry; } rb_sys_fail(0); @@ -1431,9 +1428,7 @@ udp_send(argc, argv, sock) freeaddrinfo(res0); return INT2FIX(n); } - switch (errno) { - case EINTR: - rb_thread_schedule(); + if (rb_io_wait_writable(fileno(f))) { goto retry; } } diff --git a/io.c b/io.c index a10ff06dc3..bad70da8ae 100644 --- a/io.c +++ b/io.c @@ -250,24 +250,60 @@ io_fflush(f, fptr) fptr->mode &= ~FMODE_WBUF; } -void +int 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); + + switch (errno) { + case EINTR: +#if defined(ERESTART) + case ERESTART: +#endif + rb_thread_wait_fd(f); + return Qtrue; + + case EAGAIN: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + FD_ZERO(&rfds); + FD_SET(f, &rfds); + rb_thread_select(f + 1, &rfds, NULL, NULL, NULL); + return Qtrue; + + default: + return Qfalse; + } } -void +int 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); + + switch (errno) { + case EINTR: +#if defined(ERESTART) + case ERESTART: +#endif + rb_thread_fd_writable(f); + return Qtrue; + + case EAGAIN: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + FD_ZERO(&wfds); + FD_SET(f, &wfds); + rb_thread_select(f + 1, NULL, &wfds, NULL, NULL); + return Qtrue; + + default: + return Qfalse; + } } /* writing functions */ @@ -308,20 +344,9 @@ io_write(io, str) ptr += r; n -= r; if (ferror(f)) { - switch (errno) { - case EINTR: -#if defined(ERESTART) - case ERESTART: -#endif + if (rb_io_wait_writable(fileno(f))) { 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); } @@ -571,31 +596,6 @@ 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) char *ptr; @@ -636,6 +636,9 @@ rb_io_fread(ptr, len, f) if (ferror(f)) { switch (errno) { case EINTR: +#if defined(ERESTART) + case ERESTART: +#endif clearerr(f); continue; case EAGAIN: @@ -820,7 +823,9 @@ appendline(fptr, delim, strp) TRAP_END; if (c == EOF) { if (ferror(f)) { - io_read_retryable(f, fptr->path); + if (!rb_io_wait_readable(fileno(f))) + rb_sys_fail(fptr->path); + clearerr(f); continue; } return c; @@ -1133,7 +1138,9 @@ rb_io_each_byte(io) TRAP_END; if (c == EOF) { if (ferror(f)) { - io_read_retryable(f, fptr->path); + if (!rb_io_wait_readable(fileno(f))) + rb_sys_fail(fptr->path); + clearerr(f); continue; } break; @@ -1164,7 +1171,9 @@ rb_io_getc(io) if (c == EOF) { if (ferror(f)) { - io_read_retryable(f, fptr->path); + if (!rb_io_wait_readable(fileno(f))) + rb_sys_fail(fptr->path); + clearerr(f); goto retry; } return Qnil; diff --git a/rubyio.h b/rubyio.h index 8d2a307514..80ad45932e 100644 --- a/rubyio.h +++ b/rubyio.h @@ -64,6 +64,8 @@ void rb_io_check_readable _((OpenFile*)); void rb_io_fptr_finalize _((OpenFile*)); void rb_io_synchronized _((OpenFile*)); void rb_io_check_closed _((OpenFile*)); +int rb_io_wait_readable _((int)); +int rb_io_wait_writable _((int)); VALUE rb_io_taint_check _((VALUE)); void rb_eof_error _((void));