mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.0557: no IPv6 support for channels
Problem: No IPv6 support for channels. Solution: Add IPv6 support. (Ozaki Kiichi, closes #5893)
This commit is contained in:
@@ -62,9 +62,7 @@ _anchors:
|
||||
sudo update-alternatives --install /usr/bin/lua lua /usr/bin/lua5.3 10
|
||||
fi
|
||||
before_script:
|
||||
# On travis bionic-amd64 gethostbyname() resolves "localhost" to 127.0.1.1
|
||||
# so that makes various channel tests fail.
|
||||
- sudo sed -i '/^127\.0\.1\.1\s/s/\blocalhost\b//g' /etc/hosts
|
||||
- sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0
|
||||
- sudo bash ci/load-snd-dummy.sh || true
|
||||
- sudo usermod -a -G audio $USER
|
||||
- do_test() { sg audio "sg $(id -gn) '$*'"; }
|
||||
|
@@ -120,6 +120,9 @@ Use |ch_status()| to see if the channel could be opened.
|
||||
|
||||
{address} has the form "hostname:port". E.g., "localhost:8765".
|
||||
|
||||
When using an IPv6 address, enclose it within square brackets. E.g.,
|
||||
"[2001:db8::1]:8765".
|
||||
|
||||
{options} is a dictionary with optional entries: *channel-open-options*
|
||||
|
||||
"mode" can be: *channel-mode*
|
||||
@@ -621,6 +624,9 @@ ch_open({address} [, {options}]) *ch_open()*
|
||||
{address} has the form "hostname:port", e.g.,
|
||||
"localhost:8765".
|
||||
|
||||
When using an IPv6 address, enclose it within square brackets.
|
||||
E.g., "[2001:db8::1]:8765".
|
||||
|
||||
If {options} is given it must be a |Dictionary|.
|
||||
See |channel-open-options|.
|
||||
|
||||
|
@@ -375,6 +375,7 @@ m *+hangul_input* Hangul input support |hangul|
|
||||
*+iconv* Compiled with the |iconv()| function
|
||||
*+iconv/dyn* Likewise |iconv-dynamic| |/dyn|
|
||||
T *+insert_expand* |insert_expand| Insert mode completion
|
||||
m *+ipv6* Support for IPv6 networking |channel|
|
||||
m *+job* starting and stopping jobs |job|
|
||||
S *+jumplist* |jumplist|
|
||||
B *+keymap* |'keymap'|
|
||||
|
@@ -850,7 +850,7 @@ endif
|
||||
|
||||
ifeq ($(CHANNEL),yes)
|
||||
OBJ += $(OUTDIR)/channel.o
|
||||
LIB += -lwsock32
|
||||
LIB += -lwsock32 -lws2_32
|
||||
endif
|
||||
|
||||
ifeq ($(DIRECTX),yes)
|
||||
|
@@ -469,7 +469,7 @@ CHANNEL_PRO = proto/channel.pro
|
||||
CHANNEL_OBJ = $(OBJDIR)/channel.obj
|
||||
CHANNEL_DEFS = -DFEAT_JOB_CHANNEL
|
||||
|
||||
NETBEANS_LIB = WSock32.lib
|
||||
NETBEANS_LIB = WSock32.lib Ws2_32.lib
|
||||
!endif
|
||||
|
||||
# Set which version of the CRT to use
|
||||
|
74
src/auto/configure
vendored
74
src/auto/configure
vendored
@@ -7723,7 +7723,6 @@ $as_echo "yes" >&6; }
|
||||
fi
|
||||
|
||||
if test "$enable_channel" = "yes"; then
|
||||
|
||||
if test "x$HAIKU" = "xyes"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lnetwork" >&5
|
||||
$as_echo_n "checking for socket in -lnetwork... " >&6; }
|
||||
@@ -7818,6 +7817,62 @@ fi
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiling with IPv6 networking is possible" >&5
|
||||
$as_echo_n "checking whether compiling with IPv6 networking is possible... " >&6; }
|
||||
if ${vim_cv_ipv6_networking+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
/* Check bitfields */
|
||||
struct nbbuf {
|
||||
unsigned int initDone:1;
|
||||
unsigned short signmaplen;
|
||||
};
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
/* Check creating a socket. */
|
||||
struct sockaddr_in server;
|
||||
struct addrinfo *res;
|
||||
(void)socket(AF_INET, SOCK_STREAM, 0);
|
||||
(void)htons(100);
|
||||
(void)getaddrinfo("microsoft.com", NULL, NULL, &res);
|
||||
if (errno == ECONNREFUSED)
|
||||
(void)connect(1, (struct sockaddr *)&server, sizeof(server));
|
||||
(void)freeaddrinfo(res);
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
vim_cv_ipv6_networking="yes"
|
||||
else
|
||||
vim_cv_ipv6_networking="no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $vim_cv_ipv6_networking" >&5
|
||||
$as_echo "$vim_cv_ipv6_networking" >&6; }
|
||||
|
||||
if test "x$vim_cv_ipv6_networking" = "xyes"; then
|
||||
$as_echo "#define FEAT_IPV6 1" >>confdefs.h
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
|
||||
$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
|
||||
if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
|
||||
@@ -7863,8 +7918,11 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiling with process communication is possible" >&5
|
||||
$as_echo_n "checking whether compiling with process communication is possible... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiling with IPv4 networking is possible" >&5
|
||||
$as_echo_n "checking whether compiling with IPv4 networking is possible... " >&6; }
|
||||
if ${vim_cv_ipv4_networking+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
@@ -7900,15 +7958,17 @@ main ()
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
vim_cv_ipv4_networking="yes"
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }; enable_netbeans="no"; enable_channel="no"
|
||||
vim_cv_ipv4_networking="no"; enable_netbeans="no"; enable_channel="no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $vim_cv_ipv4_networking" >&5
|
||||
$as_echo "$vim_cv_ipv4_networking" >&6; }
|
||||
fi
|
||||
fi
|
||||
if test "$enable_netbeans" = "yes"; then
|
||||
$as_echo "#define FEAT_NETBEANS_INTG 1" >>confdefs.h
|
||||
|
||||
|
335
src/channel.c
335
src/channel.c
@@ -10,6 +10,13 @@
|
||||
* Implements communication through a socket or any file handle.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
// Must include winsock2.h before windows.h since it conflicts with winsock.h
|
||||
// (included in windows.h).
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#include "vim.h"
|
||||
|
||||
#if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
|
||||
@@ -40,7 +47,7 @@
|
||||
#else
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# ifdef HAVE_LIBGEN_H
|
||||
# include <libgen.h>
|
||||
@@ -711,90 +718,38 @@ channel_gui_unregister(channel_T *channel)
|
||||
static char *e_cannot_connect = N_("E902: Cannot connect to port");
|
||||
|
||||
/*
|
||||
* Open a socket channel to "hostname":"port".
|
||||
* "waittime" is the time in msec to wait for the connection.
|
||||
* When negative wait forever.
|
||||
* Returns the channel for success.
|
||||
* Returns NULL for failure.
|
||||
*/
|
||||
channel_T *
|
||||
channel_open(
|
||||
char *hostname,
|
||||
int port_in,
|
||||
int waittime,
|
||||
void (*nb_close_cb)(void))
|
||||
{
|
||||
int sd = -1;
|
||||
struct sockaddr_in server;
|
||||
struct hostent *host;
|
||||
#ifdef MSWIN
|
||||
u_short port = port_in;
|
||||
u_long val = 1;
|
||||
#else
|
||||
int port = port_in;
|
||||
#endif
|
||||
channel_T *channel;
|
||||
int ret;
|
||||
|
||||
#ifdef MSWIN
|
||||
channel_init_winsock();
|
||||
#endif
|
||||
|
||||
channel = add_channel();
|
||||
if (channel == NULL)
|
||||
{
|
||||
ch_error(NULL, "Cannot allocate channel.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the server internet address and put into addr structure
|
||||
// fill in the socket address structure and connect to server
|
||||
vim_memset((char *)&server, 0, sizeof(server));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
if ((host = gethostbyname(hostname)) == NULL)
|
||||
{
|
||||
ch_error(channel, "in gethostbyname() in channel_open()");
|
||||
PERROR(_("E901: gethostbyname() in channel_open()"));
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
char *p;
|
||||
|
||||
// When using host->h_addr_list[0] directly ubsan warns for it to not
|
||||
// be aligned. First copy the pointer to avoid that.
|
||||
memcpy(&p, &host->h_addr_list[0], sizeof(p));
|
||||
memcpy((char *)&server.sin_addr, p, host->h_length);
|
||||
}
|
||||
|
||||
// On Mac and Solaris a zero timeout almost never works. At least wait
|
||||
// one millisecond. Let's do it for all systems, because we don't know why
|
||||
// this is needed.
|
||||
if (waittime == 0)
|
||||
waittime = 1;
|
||||
|
||||
/*
|
||||
* For Unix we need to call connect() again after connect() failed.
|
||||
* On Win32 one time is sufficient.
|
||||
*/
|
||||
static int
|
||||
channel_connect(
|
||||
channel_T *channel,
|
||||
const struct sockaddr *server_addr,
|
||||
int server_addrlen,
|
||||
int *waittime)
|
||||
{
|
||||
int sd = -1;
|
||||
#ifdef MSWIN
|
||||
u_long val = 1;
|
||||
#endif
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
long elapsed_msec = 0;
|
||||
int waitnow;
|
||||
int ret;
|
||||
|
||||
if (sd >= 0)
|
||||
sock_close(sd);
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
sd = socket(server_addr->sa_family, SOCK_STREAM, 0);
|
||||
if (sd == -1)
|
||||
{
|
||||
ch_error(channel, "in socket() in channel_open().");
|
||||
PERROR(_("E898: socket() in channel_open()"));
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
ch_error(channel, "in socket() in channel_connect().");
|
||||
PERROR(_("E898: socket() in channel_connect()"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (waittime >= 0)
|
||||
if (*waittime >= 0)
|
||||
{
|
||||
// Make connect() non-blocking.
|
||||
if (
|
||||
@@ -807,23 +762,22 @@ channel_open(
|
||||
{
|
||||
SOCK_ERRNO;
|
||||
ch_error(channel,
|
||||
"channel_open: Connect failed with errno %d", errno);
|
||||
"channel_connect: Connect failed with errno %d", errno);
|
||||
sock_close(sd);
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Try connecting to the server.
|
||||
ch_log(channel, "Connecting to %s port %d", hostname, port);
|
||||
ret = connect(sd, (struct sockaddr *)&server, sizeof(server));
|
||||
ch_log(channel, "Connecting...");
|
||||
|
||||
ret = connect(sd, server_addr, server_addrlen);
|
||||
if (ret == 0)
|
||||
// The connection could be established.
|
||||
break;
|
||||
|
||||
SOCK_ERRNO;
|
||||
if (waittime < 0 || (errno != EWOULDBLOCK
|
||||
if (*waittime < 0 || (errno != EWOULDBLOCK
|
||||
&& errno != ECONNREFUSED
|
||||
#ifdef EINPROGRESS
|
||||
&& errno != EINPROGRESS
|
||||
@@ -831,22 +785,24 @@ channel_open(
|
||||
))
|
||||
{
|
||||
ch_error(channel,
|
||||
"channel_open: Connect failed with errno %d", errno);
|
||||
"channel_connect: Connect failed with errno %d", errno);
|
||||
PERROR(_(e_cannot_connect));
|
||||
sock_close(sd);
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
else if (errno == ECONNREFUSED)
|
||||
{
|
||||
ch_error(channel, "channel_connect: Connection refused");
|
||||
sock_close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Limit the waittime to 50 msec. If it doesn't work within this
|
||||
// time we close the socket and try creating it again.
|
||||
waitnow = waittime > 50 ? 50 : waittime;
|
||||
waitnow = *waittime > 50 ? 50 : *waittime;
|
||||
|
||||
// If connect() didn't finish then try using select() to wait for the
|
||||
// connection to be made. For Win32 always use select() to wait.
|
||||
#ifndef MSWIN
|
||||
if (errno != ECONNREFUSED)
|
||||
#endif
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set rfds;
|
||||
@@ -869,17 +825,16 @@ channel_open(
|
||||
#endif
|
||||
ch_log(channel,
|
||||
"Waiting for connection (waiting %d msec)...", waitnow);
|
||||
ret = select((int)sd + 1, &rfds, &wfds, NULL, &tv);
|
||||
|
||||
ret = select((int)sd + 1, &rfds, &wfds, NULL, &tv);
|
||||
if (ret < 0)
|
||||
{
|
||||
SOCK_ERRNO;
|
||||
ch_error(channel,
|
||||
"channel_open: Connect failed with errno %d", errno);
|
||||
"channel_connect: Connect failed with errno %d", errno);
|
||||
PERROR(_(e_cannot_connect));
|
||||
sock_close(sd);
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef MSWIN
|
||||
@@ -888,9 +843,9 @@ channel_open(
|
||||
if (FD_ISSET(sd, &wfds))
|
||||
break;
|
||||
elapsed_msec = waitnow;
|
||||
if (waittime > 1 && elapsed_msec < waittime)
|
||||
if (*waittime > 1 && elapsed_msec < *waittime)
|
||||
{
|
||||
waittime -= elapsed_msec;
|
||||
*waittime -= elapsed_msec;
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
@@ -914,12 +869,17 @@ channel_open(
|
||||
))
|
||||
{
|
||||
ch_error(channel,
|
||||
"channel_open: Connect failed with errno %d",
|
||||
"channel_connect: Connect failed with errno %d",
|
||||
so_error);
|
||||
PERROR(_(e_cannot_connect));
|
||||
sock_close(sd);
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
else if (errno == ECONNREFUSED)
|
||||
{
|
||||
ch_error(channel, "channel_connect: Connection refused");
|
||||
sock_close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,25 +894,25 @@ channel_open(
|
||||
}
|
||||
|
||||
#ifndef MSWIN
|
||||
if (waittime > 1 && elapsed_msec < waittime)
|
||||
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. Select() may return early, wait until the remaining
|
||||
// "waitnow" and try again.
|
||||
waitnow -= elapsed_msec;
|
||||
waittime -= elapsed_msec;
|
||||
*waittime -= elapsed_msec;
|
||||
if (waitnow > 0)
|
||||
{
|
||||
mch_delay((long)waitnow, TRUE);
|
||||
ui_breakcheck();
|
||||
waittime -= waitnow;
|
||||
*waittime -= waitnow;
|
||||
}
|
||||
if (!got_int)
|
||||
{
|
||||
if (waittime <= 0)
|
||||
if (*waittime <= 0)
|
||||
// give it one more try
|
||||
waittime = 1;
|
||||
*waittime = 1;
|
||||
continue;
|
||||
}
|
||||
// we were interrupted, behave as if timed out
|
||||
@@ -962,13 +922,10 @@ channel_open(
|
||||
// We timed out.
|
||||
ch_error(channel, "Connection timed out");
|
||||
sock_close(sd);
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ch_log(channel, "Connection made");
|
||||
|
||||
if (waittime >= 0)
|
||||
if (*waittime >= 0)
|
||||
{
|
||||
#ifdef MSWIN
|
||||
val = 0;
|
||||
@@ -978,10 +935,151 @@ channel_open(
|
||||
#endif
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a socket channel to "hostname":"port".
|
||||
* "waittime" is the time in msec to wait for the connection.
|
||||
* When negative wait forever.
|
||||
* Returns the channel for success.
|
||||
* Returns NULL for failure.
|
||||
*/
|
||||
channel_T *
|
||||
channel_open(
|
||||
const char *hostname,
|
||||
int port,
|
||||
int waittime,
|
||||
void (*nb_close_cb)(void))
|
||||
{
|
||||
int sd = -1;
|
||||
channel_T *channel = NULL;
|
||||
#ifdef FEAT_IPV6
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res = NULL;
|
||||
struct addrinfo *addr = NULL;
|
||||
#else
|
||||
struct sockaddr_in server;
|
||||
struct hostent *host = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef MSWIN
|
||||
channel_init_winsock();
|
||||
#endif
|
||||
|
||||
channel = add_channel();
|
||||
if (channel == NULL)
|
||||
{
|
||||
ch_error(NULL, "Cannot allocate channel.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the server internet address and put into addr structure fill in the
|
||||
// socket address structure and connect to server.
|
||||
#ifdef FEAT_IPV6
|
||||
vim_memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
# ifdef AI_ADDRCONFIG
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
# endif
|
||||
// Set port number manually in order to prevent name resolution services
|
||||
// from being invoked in the environment where AI_NUMERICSERV is not
|
||||
// defined.
|
||||
if (getaddrinfo(hostname, NULL, &hints, &res) != 0)
|
||||
{
|
||||
ch_error(channel, "in getaddrinfo() in channel_open()");
|
||||
PERROR(_("E901: getaddrinfo() in channel_open()"));
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (addr = res; addr != NULL; addr = addr->ai_next)
|
||||
{
|
||||
const char *dst = hostname;
|
||||
const void *src = NULL;
|
||||
char buf[NUMBUFLEN];
|
||||
|
||||
if (addr->ai_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6 *sai = (struct sockaddr_in6 *)addr->ai_addr;
|
||||
|
||||
sai->sin6_port = htons(port);
|
||||
src = &sai->sin6_addr;
|
||||
}
|
||||
else if (addr->ai_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in *sai = (struct sockaddr_in *)addr->ai_addr;
|
||||
|
||||
sai->sin_port = htons(port);
|
||||
src = &sai->sin_addr;
|
||||
}
|
||||
if (src != NULL)
|
||||
{
|
||||
dst = inet_ntop(addr->ai_family, src, buf, sizeof(buf));
|
||||
if (dst != NULL && STRCMP(hostname, dst) != 0)
|
||||
ch_log(channel, "Resolved %s to %s", hostname, dst);
|
||||
}
|
||||
|
||||
ch_log(channel, "Trying to connect to %s port %d", dst, port);
|
||||
|
||||
// On Mac and Solaris a zero timeout almost never works. At least wait
|
||||
// one millisecond. Let's do it for all systems, because we don't know
|
||||
// why this is needed.
|
||||
if (waittime == 0)
|
||||
waittime = 1;
|
||||
|
||||
sd = channel_connect(channel, addr->ai_addr, addr->ai_addrlen,
|
||||
&waittime);
|
||||
if (sd >= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
#else
|
||||
vim_memset((char *)&server, 0, sizeof(server));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
if ((host = gethostbyname(hostname)) == NULL)
|
||||
{
|
||||
ch_error(channel, "in gethostbyname() in channel_open()");
|
||||
PERROR(_("E901: gethostbyname() in channel_open()"));
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
char *p;
|
||||
|
||||
// When using host->h_addr_list[0] directly ubsan warns for it to not
|
||||
// be aligned. First copy the pointer to avoid that.
|
||||
memcpy(&p, &host->h_addr_list[0], sizeof(p));
|
||||
memcpy((char *)&server.sin_addr, p, host->h_length);
|
||||
}
|
||||
|
||||
ch_log(channel, "Trying to connect to %s port %d", hostname, port);
|
||||
|
||||
// On Mac and Solaris a zero timeout almost never works. At least wait one
|
||||
// millisecond. Let's do it for all systems, because we don't know why
|
||||
// this is needed.
|
||||
if (waittime == 0)
|
||||
waittime = 1;
|
||||
|
||||
sd = channel_connect(channel, (struct sockaddr *)&server, sizeof(server),
|
||||
&waittime);
|
||||
#endif
|
||||
|
||||
if (sd < 0)
|
||||
{
|
||||
channel_free(channel);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ch_log(channel, "Connection made");
|
||||
|
||||
channel->CH_SOCK_FD = (sock_T)sd;
|
||||
channel->ch_nb_close_cb = nb_close_cb;
|
||||
channel->ch_hostname = (char *)vim_strsave((char_u *)hostname);
|
||||
channel->ch_port = port_in;
|
||||
channel->ch_port = port;
|
||||
channel->ch_to_be_closed |= (1U << PART_SOCK);
|
||||
|
||||
#ifdef FEAT_GUI
|
||||
@@ -1222,6 +1320,7 @@ channel_open_func(typval_T *argvars)
|
||||
char_u *p;
|
||||
char *rest;
|
||||
int port;
|
||||
int is_ipv6 = FALSE;
|
||||
jobopt_T opt;
|
||||
channel_T *channel = NULL;
|
||||
|
||||
@@ -1234,20 +1333,40 @@ channel_open_func(typval_T *argvars)
|
||||
}
|
||||
|
||||
// parse address
|
||||
if (*address == '[')
|
||||
{
|
||||
// ipv6 address
|
||||
is_ipv6 = TRUE;
|
||||
p = vim_strchr(address + 1, ']');
|
||||
if (p == NULL || *++p != ':')
|
||||
{
|
||||
semsg(_(e_invarg2), address);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p = vim_strchr(address, ':');
|
||||
if (p == NULL)
|
||||
{
|
||||
semsg(_(e_invarg2), address);
|
||||
return NULL;
|
||||
}
|
||||
*p++ = NUL;
|
||||
port = strtol((char *)p, &rest, 10);
|
||||
if (*address == NUL || port <= 0 || *rest != NUL)
|
||||
}
|
||||
port = strtol((char *)(p + 1), &rest, 10);
|
||||
if (*address == NUL || port <= 0 || port >= 65536 || *rest != NUL)
|
||||
{
|
||||
p[-1] = ':';
|
||||
semsg(_(e_invarg2), address);
|
||||
return NULL;
|
||||
}
|
||||
if (is_ipv6)
|
||||
{
|
||||
// strip '[' and ']'
|
||||
++address;
|
||||
*(p - 1) = NUL;
|
||||
}
|
||||
else
|
||||
*p = NUL;
|
||||
|
||||
// parse options
|
||||
clear_job_options(&opt);
|
||||
|
@@ -438,6 +438,9 @@
|
||||
/* Define if we have shl_load() */
|
||||
#undef HAVE_SHL_LOAD
|
||||
|
||||
/* Define if we can use IPv6 networking. */
|
||||
#undef FEAT_IPV6
|
||||
|
||||
/* Define if you want to include NetBeans integration. */
|
||||
#undef FEAT_NETBEANS_INTG
|
||||
|
||||
|
@@ -2038,17 +2038,50 @@ else
|
||||
fi
|
||||
|
||||
if test "$enable_channel" = "yes"; then
|
||||
dnl On Solaris we need the socket and nsl library.
|
||||
|
||||
dnl On Solaris we need the socket library, or on Haiku the network library.
|
||||
if test "x$HAIKU" = "xyes"; then
|
||||
AC_CHECK_LIB(network, socket)
|
||||
else
|
||||
AC_CHECK_LIB(socket, socket)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether compiling with IPv6 networking is possible], [vim_cv_ipv6_networking],
|
||||
[AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
/* Check bitfields */
|
||||
struct nbbuf {
|
||||
unsigned int initDone:1;
|
||||
unsigned short signmaplen;
|
||||
};
|
||||
], [
|
||||
/* Check creating a socket. */
|
||||
struct sockaddr_in server;
|
||||
struct addrinfo *res;
|
||||
(void)socket(AF_INET, SOCK_STREAM, 0);
|
||||
(void)htons(100);
|
||||
(void)getaddrinfo("microsoft.com", NULL, NULL, &res);
|
||||
if (errno == ECONNREFUSED)
|
||||
(void)connect(1, (struct sockaddr *)&server, sizeof(server));
|
||||
(void)freeaddrinfo(res);
|
||||
],
|
||||
[vim_cv_ipv6_networking="yes"],
|
||||
[vim_cv_ipv6_networking="no"])])
|
||||
|
||||
if test "x$vim_cv_ipv6_networking" = "xyes"; then
|
||||
AC_DEFINE(FEAT_IPV6)
|
||||
else
|
||||
dnl On Solaris we need the nsl library.
|
||||
AC_CHECK_LIB(nsl, gethostbyname)
|
||||
AC_MSG_CHECKING(whether compiling with process communication is possible)
|
||||
AC_TRY_LINK([
|
||||
AC_CACHE_CHECK([whether compiling with IPv4 networking is possible], [vim_cv_ipv4_networking],
|
||||
[AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
@@ -2072,8 +2105,9 @@ if test "$enable_channel" = "yes"; then
|
||||
if (errno == ECONNREFUSED)
|
||||
(void)connect(1, (struct sockaddr *)&server, sizeof(server));
|
||||
],
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no); enable_netbeans="no"; enable_channel="no")
|
||||
[vim_cv_ipv4_networking="yes"],
|
||||
[vim_cv_ipv4_networking="no"; enable_netbeans="no"; enable_channel="no"])])
|
||||
fi
|
||||
fi
|
||||
if test "$enable_netbeans" = "yes"; then
|
||||
AC_DEFINE(FEAT_NETBEANS_INTG)
|
||||
|
@@ -3943,6 +3943,13 @@ f_has(typval_T *argvars, typval_T *rettv)
|
||||
#endif
|
||||
},
|
||||
{"insert_expand", 1},
|
||||
{"ipv6",
|
||||
#ifdef FEAT_IPV6
|
||||
1
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
},
|
||||
{"job",
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
1
|
||||
|
@@ -7,7 +7,7 @@ int channel_unref(channel_T *channel);
|
||||
int free_unused_channels_contents(int copyID, int mask);
|
||||
void free_unused_channels(int copyID, int mask);
|
||||
void channel_gui_register_all(void);
|
||||
channel_T *channel_open(char *hostname, int port_in, int waittime, void (*nb_close_cb)(void));
|
||||
channel_T *channel_open(const char *hostname, int port, int waittime, void (*nb_close_cb)(void));
|
||||
void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err);
|
||||
void channel_set_job(channel_T *channel, job_T *job, jobopt_T *options);
|
||||
void channel_buffer_free(buf_T *buf);
|
||||
|
@@ -142,4 +142,37 @@ func CheckEnglish()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" Command to check that loopback device has IPv6 address
|
||||
command CheckIPv6 call CheckIPv6()
|
||||
func CheckIPv6()
|
||||
if !has('ipv6')
|
||||
throw 'Skipped: cannot use IPv6 networking'
|
||||
endif
|
||||
if !exists('s:ipv6_loopback')
|
||||
let s:ipv6_loopback = s:CheckIPv6Loopback()
|
||||
endif
|
||||
if !s:ipv6_loopback
|
||||
throw 'Skipped: no IPv6 address for loopback device'
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func s:CheckIPv6Loopback()
|
||||
if has('win32')
|
||||
return system('netsh interface ipv6 show interface') =~? '\<Loopback\>'
|
||||
elseif filereadable('/proc/net/if_inet6')
|
||||
return (match(readfile('/proc/net/if_inet6'), '\slo$') >= 0)
|
||||
elseif executable('ifconfig')
|
||||
for dev in ['lo0', 'lo', 'loop']
|
||||
" NOTE: On SunOS, need specify address family 'inet6' to get IPv6 info.
|
||||
if system('ifconfig ' .. dev .. ' inet6 2>/dev/null') =~? '\<inet6\>'
|
||||
\ || system('ifconfig ' .. dev .. ' 2>/dev/null') =~? '\<inet6\>'
|
||||
return v:true
|
||||
endif
|
||||
endfor
|
||||
else
|
||||
" TODO: How to check it in other platforms?
|
||||
endif
|
||||
return v:false
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@@ -161,8 +161,7 @@ func RunTheTest(test)
|
||||
exe 'call ' . a:test
|
||||
else
|
||||
try
|
||||
let s:test = a:test
|
||||
au VimLeavePre * call EarlyExit(s:test)
|
||||
au VimLeavePre * call EarlyExit(g:testfunc)
|
||||
exe 'call ' . a:test
|
||||
au! VimLeavePre
|
||||
catch /^\cskipped/
|
||||
@@ -226,11 +225,11 @@ func AfterTheTest(func_name)
|
||||
if len(v:errors) > 0
|
||||
if match(s:may_fail_list, '^' .. a:func_name) >= 0
|
||||
let s:fail_expected += 1
|
||||
call add(s:errors_expected, 'Found errors in ' . s:test . ':')
|
||||
call add(s:errors_expected, 'Found errors in ' . g:testfunc . ':')
|
||||
call extend(s:errors_expected, v:errors)
|
||||
else
|
||||
let s:fail += 1
|
||||
call add(s:errors, 'Found errors in ' . s:test . ':')
|
||||
call add(s:errors, 'Found errors in ' . g:testfunc . ':')
|
||||
call extend(s:errors, v:errors)
|
||||
endif
|
||||
let v:errors = []
|
||||
@@ -396,31 +395,31 @@ endif
|
||||
|
||||
let s:may_fail_list = []
|
||||
if $TEST_MAY_FAIL != ''
|
||||
" Split the list at commas and add () to make it match s:test.
|
||||
" Split the list at commas and add () to make it match g:testfunc.
|
||||
let s:may_fail_list = split($TEST_MAY_FAIL, ',')->map({i, v -> v .. '()'})
|
||||
endif
|
||||
|
||||
" Execute the tests in alphabetical order.
|
||||
for s:test in sort(s:tests)
|
||||
for g:testfunc in sort(s:tests)
|
||||
" Silence, please!
|
||||
set belloff=all
|
||||
let prev_error = ''
|
||||
let total_errors = []
|
||||
let g:run_nr = 1
|
||||
|
||||
" A test can set test_is_flaky to retry running the test.
|
||||
let test_is_flaky = 0
|
||||
" A test can set g:test_is_flaky to retry running the test.
|
||||
let g:test_is_flaky = 0
|
||||
|
||||
call RunTheTest(s:test)
|
||||
call RunTheTest(g:testfunc)
|
||||
|
||||
" Repeat a flaky test. Give up when:
|
||||
" - it fails again with the same message
|
||||
" - it fails five times (with a different message)
|
||||
if len(v:errors) > 0
|
||||
\ && (index(s:flaky_tests, s:test) >= 0
|
||||
\ || test_is_flaky)
|
||||
\ && (index(s:flaky_tests, g:testfunc) >= 0
|
||||
\ || g:test_is_flaky)
|
||||
while 1
|
||||
call add(s:messages, 'Found errors in ' . s:test . ':')
|
||||
call add(s:messages, 'Found errors in ' . g:testfunc . ':')
|
||||
call extend(s:messages, v:errors)
|
||||
|
||||
call add(total_errors, 'Run ' . g:run_nr . ':')
|
||||
@@ -443,7 +442,7 @@ for s:test in sort(s:tests)
|
||||
let v:errors = []
|
||||
let g:run_nr += 1
|
||||
|
||||
call RunTheTest(s:test)
|
||||
call RunTheTest(g:testfunc)
|
||||
|
||||
if len(v:errors) == 0
|
||||
" Test passed on rerun.
|
||||
@@ -452,7 +451,7 @@ for s:test in sort(s:tests)
|
||||
endwhile
|
||||
endif
|
||||
|
||||
call AfterTheTest(s:test)
|
||||
call AfterTheTest(g:testfunc)
|
||||
endfor
|
||||
|
||||
call FinishTesting()
|
||||
|
@@ -4,7 +4,7 @@ source check.vim
|
||||
CheckFeature quickfix
|
||||
|
||||
" Create the files used by the tests
|
||||
function SetUp()
|
||||
func SetUp()
|
||||
call writefile(["Line1", "Line2", "Line3"], 'Xtestfile1')
|
||||
call writefile(["Line1", "Line2", "Line3"], 'Xtestfile2')
|
||||
call writefile(["Line1", "Line2", "Line3"], 'Xtestfile3')
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Server that will accept connections from a Vim channel.
|
||||
# Used by test_channel.vim.
|
||||
@@ -235,21 +235,19 @@ def writePortInFile(port):
|
||||
f.write("{0}".format(port))
|
||||
f.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
HOST, PORT = "localhost", 0
|
||||
|
||||
def main(host, port, server_class=ThreadedTCPServer):
|
||||
# Wait half a second before opening the port to test waittime in ch_open().
|
||||
# We do want to get the port number, get that first. We cannot open the
|
||||
# socket, guess a port is free.
|
||||
if len(sys.argv) >= 2 and sys.argv[1] == 'delay':
|
||||
PORT = 13684
|
||||
writePortInFile(PORT)
|
||||
port = 13684
|
||||
writePortInFile(port)
|
||||
|
||||
print("Wait for it...")
|
||||
time.sleep(0.5)
|
||||
|
||||
server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
|
||||
ip, port = server.server_address
|
||||
server = server_class((host, port), ThreadedTCPRequestHandler)
|
||||
ip, port = server.server_address[0:2]
|
||||
|
||||
# Start a thread with the server. That thread will then start a new thread
|
||||
# for each connection.
|
||||
@@ -263,7 +261,10 @@ if __name__ == "__main__":
|
||||
# Main thread terminates, but the server continues running
|
||||
# until server.shutdown() is called.
|
||||
try:
|
||||
while server_thread.isAlive():
|
||||
while server_thread.is_alive():
|
||||
server_thread.join(1)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
server.shutdown()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main("localhost", 0)
|
||||
|
@@ -18,11 +18,21 @@ endif
|
||||
" Add ch_log() calls where you want to see what happens.
|
||||
" call ch_logfile('channellog', 'w')
|
||||
|
||||
let s:chopt = {}
|
||||
func SetUp()
|
||||
if g:testfunc =~ '_ipv6()$'
|
||||
let s:localhost = '[::1]:'
|
||||
let s:testscript = 'test_channel_6.py'
|
||||
else
|
||||
let s:localhost = 'localhost:'
|
||||
let s:testscript = 'test_channel.py'
|
||||
endif
|
||||
let s:chopt = {}
|
||||
call ch_log(g:testfunc)
|
||||
endfunc
|
||||
|
||||
" Run "testfunc" after starting the server and stop the server afterwards.
|
||||
func s:run_server(testfunc, ...)
|
||||
call RunServer('test_channel.py', a:testfunc, a:000)
|
||||
call RunServer(s:testscript, a:testfunc, a:000)
|
||||
|
||||
" communicating with a server can be flaky
|
||||
let g:test_is_flaky = 1
|
||||
@@ -54,9 +64,7 @@ func Ch_communicate(port)
|
||||
let s:chopt.drop = 'never'
|
||||
" Also add the noblock flag to try it out.
|
||||
let s:chopt.noblock = 1
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
unlet s:chopt.drop
|
||||
unlet s:chopt.noblock
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -224,13 +232,17 @@ func Ch_communicate(port)
|
||||
endfunc
|
||||
|
||||
func Test_communicate()
|
||||
call ch_log('Test_communicate()')
|
||||
call s:run_server('Ch_communicate')
|
||||
endfunc
|
||||
|
||||
func Test_communicate_ipv6()
|
||||
CheckIPv6
|
||||
call Test_communicate()
|
||||
endfunc
|
||||
|
||||
" Test that we can open two channels.
|
||||
func Ch_two_channels(port)
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
call assert_equal(v:t_channel, type(handle))
|
||||
if handle->ch_status() == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
@@ -239,7 +251,7 @@ func Ch_two_channels(port)
|
||||
|
||||
call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
|
||||
|
||||
let newhandle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let newhandle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(newhandle) == "fail"
|
||||
call assert_report("Can't open second channel")
|
||||
return
|
||||
@@ -259,9 +271,14 @@ func Test_two_channels()
|
||||
call s:run_server('Ch_two_channels')
|
||||
endfunc
|
||||
|
||||
func Test_two_channels_ipv6()
|
||||
CheckIPv6
|
||||
call Test_two_channels()
|
||||
endfunc
|
||||
|
||||
" Test that a server crash is handled gracefully.
|
||||
func Ch_server_crash(port)
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -273,10 +290,14 @@ func Ch_server_crash(port)
|
||||
endfunc
|
||||
|
||||
func Test_server_crash()
|
||||
call ch_log('Test_server_crash()')
|
||||
call s:run_server('Ch_server_crash')
|
||||
endfunc
|
||||
|
||||
func Test_server_crash_ipv6()
|
||||
CheckIPv6
|
||||
call Test_server_crash()
|
||||
endfunc
|
||||
|
||||
"""""""""
|
||||
|
||||
func Ch_handler(chan, msg)
|
||||
@@ -286,7 +307,7 @@ func Ch_handler(chan, msg)
|
||||
endfunc
|
||||
|
||||
func Ch_channel_handler(port)
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -302,14 +323,17 @@ func Ch_channel_handler(port)
|
||||
endfunc
|
||||
|
||||
func Test_channel_handler()
|
||||
call ch_log('Test_channel_handler()')
|
||||
let g:Ch_reply = ""
|
||||
let s:chopt.callback = 'Ch_handler'
|
||||
call s:run_server('Ch_channel_handler')
|
||||
let g:Ch_reply = ""
|
||||
let s:chopt.callback = function('Ch_handler')
|
||||
call s:run_server('Ch_channel_handler')
|
||||
unlet s:chopt.callback
|
||||
endfunc
|
||||
|
||||
func Test_channel_handler_ipv6()
|
||||
CheckIPv6
|
||||
call Test_channel_handler()
|
||||
endfunc
|
||||
|
||||
"""""""""
|
||||
@@ -327,7 +351,7 @@ func Ch_oneHandler(chan, msg)
|
||||
endfunc
|
||||
|
||||
func Ch_channel_zero(port)
|
||||
let handle = ('localhost:' .. a:port)->ch_open(s:chopt)
|
||||
let handle = (s:localhost .. a:port)->ch_open(s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -359,7 +383,6 @@ func Ch_channel_zero(port)
|
||||
endfunc
|
||||
|
||||
func Test_zero_reply()
|
||||
call ch_log('Test_zero_reply()')
|
||||
" Run with channel handler
|
||||
let s:has_handler = 1
|
||||
let s:chopt.callback = 'Ch_zeroHandler'
|
||||
@@ -371,6 +394,11 @@ func Test_zero_reply()
|
||||
call s:run_server('Ch_channel_zero')
|
||||
endfunc
|
||||
|
||||
func Test_zero_reply_ipv6()
|
||||
CheckIPv6
|
||||
call Test_zero_reply()
|
||||
endfunc
|
||||
|
||||
"""""""""
|
||||
|
||||
let g:Ch_reply1 = ""
|
||||
@@ -392,7 +420,7 @@ func Ch_handleRaw3(chan, msg)
|
||||
endfunc
|
||||
|
||||
func Ch_raw_one_time_callback(port)
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -410,10 +438,14 @@ func Ch_raw_one_time_callback(port)
|
||||
endfunc
|
||||
|
||||
func Test_raw_one_time_callback()
|
||||
call ch_log('Test_raw_one_time_callback()')
|
||||
call s:run_server('Ch_raw_one_time_callback')
|
||||
endfunc
|
||||
|
||||
func Test_raw_one_time_callback_ipv6()
|
||||
CheckIPv6
|
||||
call Test_raw_one_time_callback()
|
||||
endfunc
|
||||
|
||||
"""""""""
|
||||
|
||||
" Test that trying to connect to a non-existing port fails quickly.
|
||||
@@ -422,7 +454,6 @@ func Test_connect_waittime()
|
||||
" this is timing sensitive
|
||||
let g:test_is_flaky = 1
|
||||
|
||||
call ch_log('Test_connect_waittime()')
|
||||
let start = reltime()
|
||||
let handle = ch_open('localhost:9876', s:chopt)
|
||||
if ch_status(handle) != "fail"
|
||||
@@ -752,7 +783,6 @@ func Test_close_output_buffer()
|
||||
enew!
|
||||
let test_lines = ['one', 'two']
|
||||
call setline(1, test_lines)
|
||||
call ch_log('Test_close_output_buffer()')
|
||||
let options = {'out_io': 'buffer'}
|
||||
let options['out_name'] = 'buffer-output'
|
||||
let options['out_msg'] = 0
|
||||
@@ -924,17 +954,14 @@ func Run_pipe_through_sort(all, use_buffer)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_through_sort_all()
|
||||
call ch_log('Test_pipe_through_sort_all()')
|
||||
call Run_pipe_through_sort(1, 1)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_through_sort_some()
|
||||
call ch_log('Test_pipe_through_sort_some()')
|
||||
call Run_pipe_through_sort(0, 1)
|
||||
endfunc
|
||||
|
||||
func Test_pipe_through_sort_feed()
|
||||
call ch_log('Test_pipe_through_sort_feed()')
|
||||
call Run_pipe_through_sort(1, 0)
|
||||
endfunc
|
||||
|
||||
@@ -1341,16 +1368,20 @@ endfunc
|
||||
|
||||
" Test that "unlet handle" in a handler doesn't crash Vim.
|
||||
func Ch_unlet_handle(port)
|
||||
let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
|
||||
let s:channelfd = ch_open(s:localhost . a:port, s:chopt)
|
||||
eval s:channelfd->ch_sendexpr("test", {'callback': function('s:UnletHandler')})
|
||||
call WaitForAssert({-> assert_equal('what?', g:Ch_unletResponse)})
|
||||
endfunc
|
||||
|
||||
func Test_unlet_handle()
|
||||
call ch_log('Test_unlet_handle()')
|
||||
call s:run_server('Ch_unlet_handle')
|
||||
endfunc
|
||||
|
||||
func Test_unlet_handle_ipv6()
|
||||
CheckIPv6
|
||||
call Test_unlet_handle()
|
||||
endfunc
|
||||
|
||||
""""""""""
|
||||
|
||||
let g:Ch_unletResponse = ''
|
||||
@@ -1361,7 +1392,7 @@ endfunc
|
||||
|
||||
" Test that "unlet handle" in a handler doesn't crash Vim.
|
||||
func Ch_close_handle(port)
|
||||
let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
|
||||
let s:channelfd = ch_open(s:localhost . a:port, s:chopt)
|
||||
call ch_sendexpr(s:channelfd, "test", {'callback': function('Ch_CloseHandler')})
|
||||
call WaitForAssert({-> assert_equal('what?', g:Ch_unletResponse)})
|
||||
endfunc
|
||||
@@ -1370,6 +1401,23 @@ func Test_close_handle()
|
||||
call s:run_server('Ch_close_handle')
|
||||
endfunc
|
||||
|
||||
func Test_close_handle_ipv6()
|
||||
CheckIPv6
|
||||
call Test_close_handle()
|
||||
endfunc
|
||||
|
||||
""""""""""
|
||||
|
||||
func Ch_open_ipv6(port)
|
||||
let handle = ch_open('[::1]:' .. a:port, s:chopt)
|
||||
call assert_notequal('fail', ch_status(handle))
|
||||
endfunc
|
||||
|
||||
func Test_open_ipv6()
|
||||
CheckIPv6
|
||||
call s:run_server('Ch_open_ipv6')
|
||||
endfunc
|
||||
|
||||
""""""""""
|
||||
|
||||
func Test_open_fail()
|
||||
@@ -1378,6 +1426,7 @@ func Test_open_fail()
|
||||
let d = ch
|
||||
call assert_fails("let ch = ch_open('noserver', 10)", 'E474:')
|
||||
call assert_fails("let ch = ch_open('localhost:-1')", 'E475:')
|
||||
call assert_fails("let ch = ch_open('localhost:65537')", 'E475:')
|
||||
call assert_fails("let ch = ch_open('localhost:8765', {'timeout' : -1})",
|
||||
\ 'E474:')
|
||||
call assert_fails("let ch = ch_open('localhost:8765', {'axby' : 1})",
|
||||
@@ -1386,6 +1435,9 @@ func Test_open_fail()
|
||||
\ 'E475:')
|
||||
call assert_fails("let ch = ch_open('localhost:8765', {'part' : 'out'})",
|
||||
\ 'E475:')
|
||||
call assert_fails("let ch = ch_open('[::]')", 'E475:')
|
||||
call assert_fails("let ch = ch_open('[::.80')", 'E475:')
|
||||
call assert_fails("let ch = ch_open('[::]8080')", 'E475:')
|
||||
endfunc
|
||||
|
||||
func Test_ch_info_fail()
|
||||
@@ -1397,8 +1449,7 @@ endfunc
|
||||
func Ch_open_delay(port)
|
||||
" Wait up to a second for the port to open.
|
||||
let s:chopt.waittime = 1000
|
||||
let channel = ch_open('localhost:' . a:port, s:chopt)
|
||||
unlet s:chopt.waittime
|
||||
let channel = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(channel) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -1412,6 +1463,11 @@ func Test_open_delay()
|
||||
call s:run_server('Ch_open_delay', 'delay')
|
||||
endfunc
|
||||
|
||||
func Test_open_delay_ipv6()
|
||||
CheckIPv6
|
||||
call Test_open_delay()
|
||||
endfunc
|
||||
|
||||
"""""""""
|
||||
|
||||
function MyFunction(a,b,c)
|
||||
@@ -1419,7 +1475,7 @@ function MyFunction(a,b,c)
|
||||
endfunc
|
||||
|
||||
function Ch_test_call(port)
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -1438,6 +1494,11 @@ func Test_call()
|
||||
call s:run_server('Ch_test_call')
|
||||
endfunc
|
||||
|
||||
func Test_call_ipv6()
|
||||
CheckIPv6
|
||||
call Test_call()
|
||||
endfunc
|
||||
|
||||
"""""""""
|
||||
|
||||
let g:Ch_job_exit_ret = 'not yet'
|
||||
@@ -1513,7 +1574,7 @@ function MyCloseCb(ch)
|
||||
endfunc
|
||||
|
||||
function Ch_test_close_callback(port)
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -1528,8 +1589,13 @@ func Test_close_callback()
|
||||
call s:run_server('Ch_test_close_callback')
|
||||
endfunc
|
||||
|
||||
func Test_close_callback_ipv6()
|
||||
CheckIPv6
|
||||
call Test_close_callback()
|
||||
endfunc
|
||||
|
||||
function Ch_test_close_partial(port)
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -1549,6 +1615,11 @@ func Test_close_partial()
|
||||
call s:run_server('Ch_test_close_partial')
|
||||
endfunc
|
||||
|
||||
func Test_close_partial_ipv6()
|
||||
CheckIPv6
|
||||
call Test_close_partial()
|
||||
endfunc
|
||||
|
||||
func Test_job_start_fails()
|
||||
" this was leaking memory
|
||||
call assert_fails("call job_start([''])", "E474:")
|
||||
@@ -1808,7 +1879,7 @@ func Test_cwd()
|
||||
endfunc
|
||||
|
||||
function Ch_test_close_lambda(port)
|
||||
let handle = ch_open('localhost:' . a:port, s:chopt)
|
||||
let handle = ch_open(s:localhost . a:port, s:chopt)
|
||||
if ch_status(handle) == "fail"
|
||||
call assert_report("Can't open channel")
|
||||
return
|
||||
@@ -1824,6 +1895,11 @@ func Test_close_lambda()
|
||||
call s:run_server('Ch_test_close_lambda')
|
||||
endfunc
|
||||
|
||||
func Test_close_lambda_ipv6()
|
||||
CheckIPv6
|
||||
call Test_close_lambda()
|
||||
endfunc
|
||||
|
||||
func s:test_list_args(cmd, out, remove_lf)
|
||||
try
|
||||
let g:out = ''
|
||||
|
15
src/testdir/test_channel_6.py
Normal file
15
src/testdir/test_channel_6.py
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Server that will accept connections from a Vim channel.
|
||||
# Used by test_channel.vim.
|
||||
#
|
||||
# This requires Python 2.6 or later.
|
||||
|
||||
from test_channel import main, ThreadedTCPServer
|
||||
import socket
|
||||
|
||||
class ThreadedTCP6Server(ThreadedTCPServer):
|
||||
address_family = socket.AF_INET6
|
||||
|
||||
if __name__ == "__main__":
|
||||
main("::", 0, ThreadedTCP6Server)
|
@@ -1,7 +1,7 @@
|
||||
" Test whether glob()/globpath() return correct results with certain escaped
|
||||
" characters.
|
||||
|
||||
function SetUp()
|
||||
func SetUp()
|
||||
" consistent sorting of file names
|
||||
set nofileignorecase
|
||||
endfunction
|
||||
|
@@ -24,7 +24,7 @@ endfunc
|
||||
|
||||
" Do all test in a separate window to avoid E211 when we recursively
|
||||
" delete the Xtopdir directory during cleanup
|
||||
function SetUp()
|
||||
func SetUp()
|
||||
set visualbell
|
||||
set nocp viminfo+=nviminfo
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
" Tests for :hide command/modifier and 'hidden' option
|
||||
|
||||
function SetUp()
|
||||
func SetUp()
|
||||
let s:save_hidden = &hidden
|
||||
let s:save_bufhidden = &bufhidden
|
||||
let s:save_autowrite = &autowrite
|
||||
|
@@ -738,6 +738,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
557,
|
||||
/**/
|
||||
556,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user