зеркало из https://github.com/github/ruby.git
* ext/socket/init.c (wait_connectable): fix error handling code.
RB_WAITFD_OUT is turned on even though an error occur. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31424 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
4da4cb0421
Коммит
9851b0ce2f
|
@ -1,3 +1,8 @@
|
||||||
|
Wed May 4 11:42:47 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
|
* ext/socket/init.c (wait_connectable): fix error handling code.
|
||||||
|
RB_WAITFD_OUT is turned on even though an error occur.
|
||||||
|
|
||||||
Wed May 4 10:12:39 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
Wed May 4 10:12:39 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
* ext/readline/readline.c (readline_event): use rb_wait_for_single_fd().
|
* ext/readline/readline.c (readline_event): use rb_wait_for_single_fd().
|
||||||
|
|
|
@ -258,22 +258,42 @@ wait_connectable(int fd)
|
||||||
{
|
{
|
||||||
int sockerr;
|
int sockerr;
|
||||||
socklen_t sockerrlen;
|
socklen_t sockerrlen;
|
||||||
int r;
|
int revents;
|
||||||
|
int ret;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
r = rb_wait_for_single_fd(fd, RB_WAITFD_OUT|RB_WAITFD_PRI, NULL);
|
/*
|
||||||
if ((r > 0) && (r & RB_WAITFD_OUT))
|
* Stevens book says, succuessful finish turn on RB_WAITFD_OUT and
|
||||||
return 0;
|
* failure finish turn on both RB_WAITFD_IN and RB_WAITFD_OUT.
|
||||||
|
*/
|
||||||
|
revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, NULL);
|
||||||
|
|
||||||
|
if (revents & (RB_WAITFD_IN|RB_WAITFD_OUT)) {
|
||||||
sockerrlen = (socklen_t)sizeof(sockerr);
|
sockerrlen = (socklen_t)sizeof(sockerr);
|
||||||
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr,
|
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen);
|
||||||
&sockerrlen) == 0) {
|
|
||||||
|
/*
|
||||||
|
* Solaris getsockopt(SO_ERROR) return -1 and set errno
|
||||||
|
* in getsockopt(). Let's return immediately.
|
||||||
|
*/
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
if (sockerr == 0)
|
if (sockerr == 0)
|
||||||
continue; /* workaround for winsock */
|
continue; /* workaround for winsock */
|
||||||
|
|
||||||
|
/* BSD and Linux use sockerr. */
|
||||||
errno = sockerr;
|
errno = sockerr;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
|
if ((revents & (RB_WAITFD_IN|RB_WAITFD_OUT)) == RB_WAITFD_OUT) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
|
|
Загрузка…
Ссылка в новой задаче