To: vim_dev@googlegroups.com Subject: Patch 7.4.1524 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1524 Problem: Channel test fails on BSD. Solution: Break out of the loop when connect() succeeds. (Ozaki Kiichi) Files: src/channel.c *** ../vim-7.4.1523/src/channel.c 2016-03-08 20:12:40.919638594 +0100 --- src/channel.c 2016-03-08 22:30:05.709000950 +0100 *************** *** 587,593 **** u_long val = 1; #else int port = port_in; - struct timeval start_tv; #endif channel_T *channel; int ret; --- 587,592 ---- *************** *** 629,634 **** --- 628,637 ---- */ while (TRUE) { + #ifndef WIN32 + long elapsed_msec = 0; + #endif + if (sd >= 0) sock_close(sd); sd = socket(AF_INET, SOCK_STREAM, 0); *************** *** 664,691 **** ch_logsn(channel, "Connecting to %s port %d", hostname, port); ret = connect(sd, (struct sockaddr *)&server, sizeof(server)); SOCK_ERRNO; ! if (ret < 0) ! { ! if (errno != EWOULDBLOCK ! && errno != ECONNREFUSED #ifdef EINPROGRESS ! && errno != EINPROGRESS #endif ! ) ! { ! ch_errorn(channel, ! "channel_open: Connect failed with errno %d", errno); ! PERROR(_(e_cannot_connect)); ! sock_close(sd); ! channel_free(channel); ! return NULL; ! } } ! /* If we don't block and connect() failed then try using select() to ! * wait for the connection to be made. */ ! if (waittime >= 0 && ret < 0) { struct timeval tv; fd_set rfds; --- 667,697 ---- ch_logsn(channel, "Connecting to %s port %d", hostname, port); ret = connect(sd, (struct sockaddr *)&server, sizeof(server)); + if (ret == 0) + /* The connection could be established. */ + break; + SOCK_ERRNO; ! if (waittime < 0 || (errno != EWOULDBLOCK ! && errno != ECONNREFUSED #ifdef EINPROGRESS ! && errno != EINPROGRESS #endif ! )) ! { ! ch_errorn(channel, ! "channel_open: Connect failed with errno %d", errno); ! PERROR(_(e_cannot_connect)); ! sock_close(sd); ! channel_free(channel); ! return NULL; } ! /* If connect() didn't finish then try using select() to wait for the ! * connection to be made. */ ! #ifndef WIN32 ! if (errno != ECONNREFUSED) ! #endif { struct timeval tv; fd_set rfds; *************** *** 693,698 **** --- 699,706 ---- #ifndef WIN32 int so_error = 0; socklen_t so_error_len = sizeof(so_error); + struct timeval start_tv; + struct timeval end_tv; #endif FD_ZERO(&rfds); *************** *** 723,741 **** #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 /* 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 able to connect. ! * We detect an failure to connect when either 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 --- 731,750 ---- #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)) ! break; #else /* 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 able to connect. ! * We detect a failure to connect when either 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 *************** *** 754,802 **** } } ! if (!FD_ISSET(sd, &wfds) || so_error != 0) #endif ! { ! #ifndef WIN32 ! struct timeval end_tv; ! long elapsed_msec; ! gettimeofday(&end_tv, NULL); ! elapsed_msec = (end_tv.tv_sec - start_tv.tv_sec) * 1000 ! + (end_tv.tv_usec - start_tv.tv_usec) / 1000; ! if (waittime > 1 && elapsed_msec < waittime) ! { ! /* The port isn't ready but we also didn't get an error. ! * This happens when the server didn't open the socket ! * yet. Wait a bit and try again. */ ! mch_delay(waittime < 50 ? (long)waittime : 50L, TRUE); ! ui_breakcheck(); ! if (!got_int) ! { ! /* reduce the waittime by the elapsed time and the 50 ! * msec delay (or a bit more) */ ! waittime -= elapsed_msec; ! if (waittime > 50) ! waittime -= 50; ! else ! waittime = 1; ! continue; ! } ! /* we were interrupted, behave as if timed out */ ! } ! #endif ! /* We timed out. */ ! ch_error(channel, "Connection timed out"); ! sock_close(sd); ! channel_free(channel); ! return NULL; } ! ! ch_log(channel, "Connection made"); ! break; } } if (waittime >= 0) { #ifdef _WIN32 --- 763,810 ---- } } ! if (FD_ISSET(sd, &wfds) && so_error == 0) ! /* Did not detect an error, connection is established. */ ! break; ! ! gettimeofday(&end_tv, NULL); ! elapsed_msec = (end_tv.tv_sec - start_tv.tv_sec) * 1000 ! + (end_tv.tv_usec - start_tv.tv_usec) / 1000; #endif ! } ! #ifndef WIN32 ! if (waittime > 1 && elapsed_msec < waittime) ! { ! /* The port isn't ready but we also didn't get an error. ! * This happens when the server didn't open the socket ! * yet. Wait a bit and try again. */ ! mch_delay(waittime < 50 ? (long)waittime : 50L, TRUE); ! ui_breakcheck(); ! if (!got_int) ! { ! /* reduce the waittime by the elapsed time and the 50 ! * msec delay (or a bit more) */ ! waittime -= elapsed_msec; ! if (waittime > 50) ! waittime -= 50; ! else ! waittime = 1; ! continue; } ! /* we were interrupted, behave as if timed out */ } + #endif + + /* We timed out. */ + ch_error(channel, "Connection timed out"); + sock_close(sd); + channel_free(channel); + return NULL; } + ch_log(channel, "Connection made"); + if (waittime >= 0) { #ifdef _WIN32 *** ../vim-7.4.1523/src/version.c 2016-03-08 20:58:25.066925814 +0100 --- src/version.c 2016-03-08 22:31:55.107837134 +0100 *************** *** 745,746 **** --- 745,748 ---- { /* Add new patch number below this line */ + /**/ + 1524, /**/ -- Shift happens. -- Doppler /// 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 ///