To: vim_dev@googlegroups.com Subject: Patch 7.4.1457 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1457 Problem: Opening a channel with select() is not done properly. Solution: Also used read-fds. Use getsockopt() to check for errors. (Ozaki Kiichi) Files: src/channel.c *** ../vim-7.4.1456/src/channel.c 2016-02-28 19:30:20.360625771 +0100 --- src/channel.c 2016-02-28 20:37:21.502571714 +0100 *************** *** 28,33 **** --- 28,35 ---- # define ECONNREFUSED WSAECONNREFUSED # undef EWOULDBLOCK # define EWOULDBLOCK WSAEWOULDBLOCK + # undef EINPROGRESS + # define EINPROGRESS WSAEINPROGRESS # ifdef EINTR # undef EINTR # endif *************** *** 550,557 **** #else int port = port_in; struct timeval start_tv; - int so_error; - socklen_t so_error_len = sizeof(so_error); #endif channel_T *channel; int ret; --- 552,557 ---- *************** *** 633,639 **** { if (errno != EWOULDBLOCK && errno != ECONNREFUSED - #ifdef EINPROGRESS && errno != EINPROGRESS #endif --- 633,638 ---- *************** *** 653,666 **** if (waittime >= 0 && ret < 0) { struct timeval tv; fd_set wfds; ! #if defined(__APPLE__) && __APPLE__ == 1 ! # define PASS_RFDS ! fd_set rfds; FD_ZERO(&rfds); FD_SET(sd, &rfds); - #endif FD_ZERO(&wfds); FD_SET(sd, &wfds); --- 652,664 ---- if (waittime >= 0 && ret < 0) { struct timeval tv; + fd_set rfds; fd_set wfds; ! int so_error = 0; ! socklen_t so_error_len = sizeof(so_error); FD_ZERO(&rfds); FD_SET(sd, &rfds); FD_ZERO(&wfds); FD_SET(sd, &wfds); *************** *** 671,683 **** #endif ch_logn(channel, "Waiting for connection (waittime %d msec)...", waittime); ! ret = select((int)sd + 1, ! #ifdef PASS_RFDS ! &rfds, ! #else ! NULL, ! #endif ! &wfds, NULL, &tv); if (ret < 0) { --- 669,675 ---- #endif ch_logn(channel, "Waiting for connection (waittime %d msec)...", waittime); ! ret = select((int)sd + 1, &rfds, &wfds, NULL, &tv); if (ret < 0) { *************** *** 689,718 **** channel_free(channel); return NULL; } ! #ifdef PASS_RFDS ! if (ret == 0 && FD_ISSET(sd, &rfds) && FD_ISSET(sd, &wfds)) ! { ! /* For OS X, this implies error. See tcp(4). */ ! ch_error(channel, "channel_open: Connect failed"); ! EMSG(_(e_cannot_connect)); ! sock_close(sd); ! channel_free(channel); ! return NULL; ! } ! #endif ! #ifdef WIN32 ! /* On Win32 select() is expected to work and wait for up to the ! * waittime for the socket to be open. */ ! if (!FD_ISSET(sd, &wfds) || ret == 0) ! #else ! /* See socket(7) for the behavior on Linux-like systems: * After putting the socket in non-blocking mode, connect() will * return EINPROGRESS, select() will not wait (as if writing is * possible), need to use getsockopt() to check if the socket is ! * actually open. */ ! getsockopt(sd, SOL_SOCKET, SO_ERROR, &so_error, &so_error_len); ! if (!FD_ISSET(sd, &wfds) || ret == 0 || so_error != 0) #endif { #ifndef WIN32 struct timeval end_tv; --- 681,719 ---- channel_free(channel); return NULL; } ! ! /* On Win32: select() is expected to work and wait for up to the ! * waittime for the socket to be open. ! * On Linux-like systems: See socket(7) for the behavior * After putting the socket in non-blocking mode, connect() will * return EINPROGRESS, select() will not wait (as if writing is * possible), need to use getsockopt() to check if the socket is ! * actually connect. ! * We detect an failure to connect when both read and write fds ! * are set. Use getsockopt() to find out what kind of failure. */ ! if (FD_ISSET(sd, &rfds) && FD_ISSET(sd, &wfds)) ! { ! ret = getsockopt(sd, ! SOL_SOCKET, SO_ERROR, &so_error, &so_error_len); ! if (ret < 0 || (so_error != 0 ! && so_error != EWOULDBLOCK ! && so_error != ECONNREFUSED ! #ifdef EINPROGRESS ! && so_error != EINPROGRESS #endif + )) + { + ch_errorn(channel, + "channel_open: Connect failed with errno %d", + so_error); + PERROR(_(e_cannot_connect)); + sock_close(sd); + channel_free(channel); + return NULL; + } + } + + if (!FD_ISSET(sd, &wfds) || so_error != 0) { #ifndef WIN32 struct timeval end_tv; *** ../vim-7.4.1456/src/version.c 2016-02-28 20:13:14.237733718 +0100 --- src/version.c 2016-02-28 20:51:15.593837802 +0100 *************** *** 745,746 **** --- 745,748 ---- { /* Add new patch number below this line */ + /**/ + 1457, /**/ -- (letter from Mark to Mike, about the film's probable certificate) I would like to get back to the Censor and agree to lose the shits, take the odd Jesus Christ out and lose Oh fuck off, but to retain 'fart in your general direction', 'castanets of your testicles' and 'oral sex' and ask him for an 'A' rating on that basis. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///