]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 7.4.1263 v7.4.1263
authorBram Moolenaar <Bram@vim.org>
Fri, 5 Feb 2016 21:36:41 +0000 (22:36 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 5 Feb 2016 21:36:41 +0000 (22:36 +0100)
Problem:    ch_open() hangs when the server isn't running.
Solution:   Add a timeout. Use a dict to pass arguments. (Yasuhiro Matsumoto)

runtime/doc/channel.txt
runtime/doc/eval.txt
src/channel.c
src/eval.c
src/netbeans.c
src/os_win32.c
src/proto/channel.pro
src/testdir/test_channel.vim
src/version.c

index 31b55cdf3a4daa9d5482d343aca4c7ee6447276a..0bc98f191ed8d5a7616700bd1249d7f5515553b9 100644 (file)
@@ -1,4 +1,4 @@
-*channel.txt*      For Vim version 7.4.  Last change: 2016 Feb 04
+*channel.txt*      For Vim version 7.4.  Last change: 2016 Feb 05
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -32,7 +32,7 @@ $VIMRUNTIME/tools/demoserver.py
 Run it in one terminal.  We will call this T1.
 
 Run Vim in another terminal.  Connect to the demo server with: >
-       let handle = ch_open('localhost:8765', 'json')
+       let handle = ch_open('localhost:8765')
 
 In T1 you should see:
        === socket opened === ~
@@ -62,23 +62,25 @@ To handle asynchronous communication a callback needs to be used: >
 Instead of giving a callback with every send call, it can also be specified
 when opening the channel: >
        call ch_close(handle)
-       let handle = ch_open('localhost:8765', 'json', "MyHandler")
+       let handle = ch_open('localhost:8765', {'callback': "MyHandler"})
        call ch_sendexpr(handle, 'hello!', 0)
 
 ==============================================================================
 2. Opening a channel                                   *channel-open*
 
 To open a channel: >
-    let handle = ch_open({address}, {mode}, {callback})
+    let handle = ch_open({address} [, {argdict}])
 
 {address} has the form "hostname:port".  E.g., "localhost:8765".
 
-{mode} can be:                                         *channel-mode*
-       "json" - Use JSON, see below; most convenient way
+{argdict} is a dictionary with optional entries:
+
+"mode" can be:                                         *channel-mode*
+       "json" - Use JSON, see below; most convenient way. Default.
        "raw"  - Use raw messages
 
                                                        *channel-callback*
-{callback} is a function that is called when a message is received that is not
+"callback" is a function that is called when a message is received that is not
 handled otherwise.  It gets two arguments: the channel handle and the received
 message. Example: >
        func Handle(handle, msg)
@@ -86,16 +88,28 @@ message. Example: >
        endfunc
        let handle = ch_open("localhost:8765", 'json', "Handle")
 
-When {mode} is "json" the "msg" argument is the body of the received message,
+"waittime" is the time to wait for the connection to be made in milliseconds.
+The default is zero, don't wait, which is useful if the server is supposed to
+be running already.  A negative number waits forever.
+
+"timeout" is the time to wait for a request when blocking, using
+ch_sendexpr().  Again in millisecons.  The default si 2000 (2 seconds).
+
+When "mode" is "json" the "msg" argument is the body of the received message,
 converted to Vim types.
-When {mode} is "raw" the "msg" argument is the whole message as a string.
+When "mode" is "raw" the "msg" argument is the whole message as a string.
 
-When {mode} is "json" the {callback} is optional.  When omitted it is only
+When "mode" is "json" the "callback" is optional.  When omitted it is only
 possible to receive a message after sending one.
 
 The handler can be added or changed later: >
     call ch_setcallback(handle, {callback})
-When {callback} is empty (zero or an empty string) the handler is removed.
+When "callback is empty (zero or an empty string) the handler is removed.
+NOT IMPLEMENTED YET
+
+The timeout can be changed later: >
+    call ch_settimeout(handle, {msec})
+NOT IMPLEMENTED YET
 
 Once done with the channel, disconnect it like this: >
     call ch_close(handle)
index 49b7b0f98979d1856d2e60fd1622b9922fa447d2..c812d0a3d1e95fa584eac575a640e65456767645 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 7.4.  Last change: 2016 Feb 04
+*eval.txt*     For Vim version 7.4.  Last change: 2016 Feb 05
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1811,8 +1811,7 @@ call( {func}, {arglist} [, {dict}])
                                any     call {func} with arguments {arglist}
 ceil( {expr})                  Float   round {expr} up
 ch_close( {handle})            none    close a channel
-ch_open( {address}, {mode} [, {callback}])
-                               Number  open a channel
+ch_open( {address} [, {argdict})] Number open a channel to {address}
 ch_sendexpr( {handle}, {expr} [, {callback}])
                                any     send {expr} over JSON channel {handle}
 ch_sendraw( {handle}, {string} [, {callback}])
@@ -2670,7 +2669,7 @@ confirm({msg} [, {choices} [, {default} [, {type}]]])
 ch_close({handle})                                     *ch_close()*
                Close channel {handle}.  See |channel|.
 
-ch_open({address}, {mode} [, {callback}])              *ch_open()*
+ch_open({address} [, {argdict}])                               *ch_open()*
                Open a channel to {address}.  See |channel|.
                Returns the channel handle on success.  Returns a negative
                number for failure.
@@ -2678,11 +2677,19 @@ ch_open({address}, {mode} [, {callback}])               *ch_open()*
                {address} has the form "hostname:port", e.g.,
                "localhost:8765".
 
-               {mode} is either "json" or "raw".  See |channel-mode| for the
-               meaning.
-
-               {callback} is a function that handles received messages on the
-               channel.  See |channel-callback|.
+               If {argdict} is given it must be a |Directory|.  The optional
+               items are:
+                       mode        "raw" or "json".
+                                   Default "json".
+                       callback    function to call for requests with a zero
+                                   sequence number.  See |channel-callback|.
+                                   Default: none.
+                       waittime    Specify connect timeout as milliseconds.
+                                   Negative means forever.
+                                   Default: 0.
+                       timeout     Specify response read timeout value as
+                                   milliseconds. 
+                                   Default: 2000.
 
 ch_sendexpr({handle}, {expr} [, {callback}])           *ch_sendexpr()*
                Send {expr} over JSON channel {handle}.  See |channel-use|.
index 7f40860fd16652f07880ca9927b498d4993b0fa9..cab920c22b184d1381722c05b8da0dc817c3ed3f 100644 (file)
@@ -42,6 +42,8 @@ static void chlog(int send, char_u *buf);
 # define SOCK_ERRNO errno = WSAGetLastError()
 # undef ECONNREFUSED
 # define ECONNREFUSED WSAECONNREFUSED
+# undef EWOULDBLOCK
+# define EWOULDBLOCK WSAEWOULDBLOCK
 # ifdef EINTR
 #  undef EINTR
 # endif
@@ -119,6 +121,8 @@ typedef struct {
 
     int              ch_json_mode;     /* TRUE for a json channel */
     jsonq_T   ch_json_head;    /* dummy node, header for circular queue */
+
+    int       ch_timeout;      /* request timeout in msec */
 } channel_T;
 
 /*
@@ -133,6 +137,48 @@ static int channel_count = 0;
  */
 FILE *debugfd = NULL;
 
+#ifdef _WIN32
+# undef PERROR
+# define PERROR(msg) (void)emsg3((char_u *)"%s: %s", \
+       (char_u *)msg, (char_u *)strerror_win32(errno))
+
+    static char *
+strerror_win32(int eno)
+{
+    static LPVOID msgbuf = NULL;
+    char_u *ptr;
+
+    if (msgbuf)
+       LocalFree(msgbuf);
+    FormatMessage(
+       FORMAT_MESSAGE_ALLOCATE_BUFFER |
+       FORMAT_MESSAGE_FROM_SYSTEM |
+       FORMAT_MESSAGE_IGNORE_INSERTS,
+       NULL,
+       eno,
+       MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
+       (LPTSTR) &msgbuf,
+       0,
+       NULL);
+    /* chomp \r or \n */
+    for (ptr = (char_u *)msgbuf; *ptr; ptr++)
+       switch (*ptr)
+       {
+           case '\r':
+               STRMOVE(ptr, ptr + 1);
+               ptr--;
+               break;
+           case '\n':
+               if (*(ptr + 1) == '\0')
+                   *ptr = '\0';
+               else
+                   *ptr = ' ';
+               break;
+       }
+    return msgbuf;
+}
+#endif
+
 /*
  * Add a new channel slot, return the index.
  * The channel isn't actually used into ch_fd is set >= 0;
@@ -182,6 +228,8 @@ add_channel(void)
     ch->ch_json_head.next = &ch->ch_json_head;
     ch->ch_json_head.prev = &ch->ch_json_head;
 
+    ch->ch_timeout = 2000;
+
     return channel_count++;
 }
 
@@ -303,17 +351,19 @@ channel_gui_unregister(int idx)
  * Returns a negative number for failure.
  */
     int
-channel_open(char *hostname, int port_in, void (*close_cb)(void))
+channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void))
 {
     int                        sd;
     struct sockaddr_in server;
     struct hostent *   host;
 #ifdef WIN32
     u_short            port = port_in;
+    u_long             val = 1;
 #else
     int                        port = port_in;
 #endif
     int                        idx;
+    int                        ret;
 
 #ifdef WIN32
     channel_init_winsock();
@@ -348,63 +398,121 @@ channel_open(char *hostname, int port_in, void (*close_cb)(void))
     }
     memcpy((char *)&server.sin_addr, host->h_addr, host->h_length);
 
-    /* Connect to server */
-    if (connect(sd, (struct sockaddr *)&server, sizeof(server)))
+    if (waittime >= 0)
     {
-       SOCK_ERRNO;
-       CHERROR("channel_open: Connect failed with errno %d\n", errno);
-       if (errno == ECONNREFUSED)
+       /* Make connect non-blocking. */
+       if (
+#ifdef _WIN32
+           ioctlsocket(sd, FIONBIO, &val) < 0
+#else
+           fcntl(sd, F_SETFL, O_NONBLOCK) < 0
+#endif
+          )
        {
+           SOCK_ERRNO;
+           CHERROR("channel_open: Connect failed with errno %d\n", errno);
            sock_close(sd);
-           if ((sd = (sock_T)socket(AF_INET, SOCK_STREAM, 0)) == (sock_T)-1)
-           {
-               SOCK_ERRNO;
-               CHERROR("socket() retry in channel_open()\n", "");
-               PERROR("E900: socket() retry in channel_open()");
-               return -1;
-           }
-           if (connect(sd, (struct sockaddr *)&server, sizeof(server)))
-           {
-               int retries = 36;
-               int success = FALSE;
+           return -1;
+       }
+    }
 
-               SOCK_ERRNO;
-               while (retries-- && ((errno == ECONNREFUSED)
-                                                        || (errno == EINTR)))
-               {
-                   CHERROR("retrying...\n", "");
-                   mch_delay(3000L, TRUE);
-                   ui_breakcheck();
-                   if (got_int)
-                   {
-                       errno = EINTR;
-                       break;
-                   }
-                   if (connect(sd, (struct sockaddr *)&server,
-                                                        sizeof(server)) == 0)
-                   {
-                       success = TRUE;
-                       break;
-                   }
-                   SOCK_ERRNO;
-               }
-               if (!success)
-               {
-                   /* Get here when the server can't be found. */
-                   CHERROR("Cannot connect to port after retry\n", "");
-                   PERROR(_("E899: Cannot connect to port after retry2"));
-                   sock_close(sd);
-                   return -1;
-               }
-           }
+    /* Try connecting to the server. */
+    ret = connect(sd, (struct sockaddr *)&server, sizeof(server));
+    SOCK_ERRNO;
+    if (ret < 0)
+    {
+       if (errno != EWOULDBLOCK && errno != EINPROGRESS)
+       {
+           CHERROR("channel_open: Connect failed with errno %d\n", errno);
+           CHERROR("Cannot connect to port\n", "");
+           PERROR(_("E902: Cannot connect to port"));
+           sock_close(sd);
+           return -1;
        }
-       else
+    }
+
+    if (waittime >= 0)
+    {
+       struct timeval  tv;
+       fd_set          rfds, wfds;
+
+       FD_ZERO(&rfds);
+       FD_ZERO(&wfds);
+       FD_SET(sd, &rfds);
+       FD_SET(sd, &wfds);
+       tv.tv_sec = waittime;
+       tv.tv_usec = 0;
+       ret = select((int)sd+1, &rfds, &wfds, NULL, &tv);
+       if (ret < 0)
+       {
+           SOCK_ERRNO;
+           CHERROR("channel_open: Connect failed with errno %d\n", errno);
+           CHERROR("Cannot connect to port\n", "");
+           PERROR(_("E902: Cannot connect to port"));
+           sock_close(sd);
+           return -1;
+       }
+       if (!FD_ISSET(sd, &rfds) && !FD_ISSET(sd, &wfds))
        {
+           errno = ECONNREFUSED;
            CHERROR("Cannot connect to port\n", "");
            PERROR(_("E902: Cannot connect to port"));
            sock_close(sd);
            return -1;
        }
+
+#ifdef _WIN32
+       val = 0;
+       ioctlsocket(sd, FIONBIO, &val);
+#else
+       fcntl(sd, F_SETFL, 0);
+#endif
+    }
+
+    if (errno == ECONNREFUSED)
+    {
+       sock_close(sd);
+       if ((sd = (sock_T)socket(AF_INET, SOCK_STREAM, 0)) == (sock_T)-1)
+       {
+           SOCK_ERRNO;
+           CHERROR("socket() retry in channel_open()\n", "");
+           PERROR("E900: socket() retry in channel_open()");
+           return -1;
+       }
+       if (connect(sd, (struct sockaddr *)&server, sizeof(server)))
+       {
+           int retries = 36;
+           int success = FALSE;
+
+           SOCK_ERRNO;
+           while (retries-- && ((errno == ECONNREFUSED)
+                                                    || (errno == EINTR)))
+           {
+               CHERROR("retrying...\n", "");
+               mch_delay(3000L, TRUE);
+               ui_breakcheck();
+               if (got_int)
+               {
+                   errno = EINTR;
+                   break;
+               }
+               if (connect(sd, (struct sockaddr *)&server,
+                                                    sizeof(server)) == 0)
+               {
+                   success = TRUE;
+                   break;
+               }
+               SOCK_ERRNO;
+           }
+           if (!success)
+           {
+               /* Get here when the server can't be found. */
+               CHERROR("Cannot connect to port after retry\n", "");
+               PERROR(_("E899: Cannot connect to port after retry2"));
+               sock_close(sd);
+               return -1;
+           }
+       }
     }
 
     channels[idx].ch_fd = sd;
@@ -426,6 +534,15 @@ channel_set_json_mode(int idx, int json_mode)
     channels[idx].ch_json_mode = json_mode;
 }
 
+/*
+ * Set the read timeout of channel "idx".
+ */
+    void
+channel_set_timeout(int idx, int timeout)
+{
+    channels[idx].ch_timeout = timeout;
+}
+
 /*
  * Set the callback for channel "idx".
  */
@@ -898,6 +1015,7 @@ channel_close(int idx)
 #endif
        vim_free(channel->ch_callback);
        channel->ch_callback = NULL;
+       channel->ch_timeout = 2000;
 
        while (channel_peek(idx) != NULL)
            vim_free(channel_get(idx));
@@ -1148,9 +1266,8 @@ channel_read_block(int idx)
 {
     if (channel_peek(idx) == NULL)
     {
-       /* Wait for up to 2 seconds.
-        * TODO: use timeout set on the channel. */
-       if (channel_wait(channels[idx].ch_fd, 2000) == FAIL)
+       /* Wait for up to the channel timeout. */
+       if (channel_wait(channels[idx].ch_fd, channels[idx].ch_timeout) == FAIL)
            return NULL;
        channel_read(idx);
     }
@@ -1161,7 +1278,7 @@ channel_read_block(int idx)
 /*
  * Read one JSON message from channel "ch_idx" with ID "id" and store the
  * result in "rettv".
- * Blocks until the message is received.
+ * Blocks until the message is received or the timeout is reached.
  */
     int
 channel_read_json_block(int ch_idx, int id, typval_T **rettv)
@@ -1183,10 +1300,10 @@ channel_read_json_block(int ch_idx, int id, typval_T **rettv)
            if (channel_parse_messages())
                continue;
 
-           /* Wait for up to 2 seconds.
-            * TODO: use timeout set on the channel. */
+           /* Wait for up to the channel timeout. */
            if (channels[ch_idx].ch_fd < 0
-                       || channel_wait(channels[ch_idx].ch_fd, 2000) == FAIL)
+                       || channel_wait(channels[ch_idx].ch_fd,
+                                        channels[ch_idx].ch_timeout) == FAIL)
                break;
            channel_read(ch_idx);
        }
index 9549ed85b530b06bc73915e78810ee93a6255a8c..50b1b2aef932f9d1d5bd8e8b757a556a50cb4353 100644 (file)
@@ -8005,7 +8005,7 @@ static struct fst
 #endif
 #ifdef FEAT_CHANNEL
     {"ch_close",       1, 1, f_ch_close},
-    {"ch_open",                2, 3, f_ch_open},
+    {"ch_open",                1, 2, f_ch_open},
     {"ch_sendexpr",    2, 3, f_ch_sendexpr},
     {"ch_sendraw",     2, 3, f_ch_sendraw},
 #endif
@@ -9743,21 +9743,23 @@ f_ch_open(typval_T *argvars, typval_T *rettv)
     char_u     *address;
     char_u     *mode;
     char_u     *callback = NULL;
-    char_u     buf1[NUMBUFLEN];
     char_u     *p;
+    char       *rest;
     int                port;
-    int                json_mode = FALSE;
+    int                waittime = 0;
+    int                timeout = 2000;
+    int                json_mode = TRUE;
+    int                ch_idx;
 
     /* default: fail */
     rettv->vval.v_number = -1;
 
     address = get_tv_string(&argvars[0]);
-    mode = get_tv_string_buf(&argvars[1], buf1);
-    if (argvars[2].v_type != VAR_UNKNOWN)
+    if (argvars[1].v_type != VAR_UNKNOWN
+        && (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL))
     {
-       callback = get_callback(&argvars[2]);
-       if (callback == NULL)
-           return;
+       EMSG(_(e_invarg));
+       return;
     }
 
     /* parse address */
@@ -9768,30 +9770,52 @@ f_ch_open(typval_T *argvars, typval_T *rettv)
        return;
     }
     *p++ = NUL;
-    port = atoi((char *)p);
-    if (*address == NUL || port <= 0)
+    port = strtol((char *)p, &rest, 10);
+    if (*address == NUL || port <= 0 || *rest != NUL)
     {
        p[-1] = ':';
        EMSG2(_(e_invarg2), address);
        return;
     }
 
-    /* parse mode */
-    if (STRCMP(mode, "json") == 0)
-       json_mode = TRUE;
-    else if (STRCMP(mode, "raw") != 0)
+    if (argvars[1].v_type == VAR_DICT)
+    {
+       /* parse argdict */
+       dict_T  *dict = argvars[1].vval.v_dict;
+
+       if (dict_find(dict, (char_u *)"mode", -1) != NULL)
+       {
+           mode = get_dict_string(dict, (char_u *)"mode", FALSE);
+           if (STRCMP(mode, "raw") == 0)
+               json_mode = FALSE;
+           else if (STRCMP(mode, "json") != 0)
+           {
+               EMSG2(_(e_invarg2), mode);
+               return;
+           }
+       }
+       if (dict_find(dict, (char_u *)"waittime", -1) != NULL)
+           waittime = get_dict_number(dict, (char_u *)"waittime");
+       if (dict_find(dict, (char_u *)"timeout", -1) != NULL)
+           timeout = get_dict_number(dict, (char_u *)"timeout");
+       if (dict_find(dict, (char_u *)"callback", -1) != NULL)
+           callback = get_dict_string(dict, (char_u *)"callback", FALSE);
+    }
+    if (waittime < 0 || timeout < 0)
     {
-       EMSG2(_(e_invarg2), mode);
+       EMSG(_(e_invarg));
        return;
     }
 
-    rettv->vval.v_number = channel_open((char *)address, port, NULL);
-    if (rettv->vval.v_number >= 0)
+    ch_idx = channel_open((char *)address, port, waittime, NULL);
+    if (ch_idx >= 0)
     {
-       channel_set_json_mode(rettv->vval.v_number, json_mode);
+       channel_set_json_mode(ch_idx, json_mode);
+       channel_set_timeout(ch_idx, timeout);
        if (callback != NULL && *callback != NUL)
-           channel_set_callback(rettv->vval.v_number, callback);
+           channel_set_callback(ch_idx, callback);
     }
+    rettv->vval.v_number = ch_idx;
 }
 
 /*
index 6f3c4e1a2707c00a54d5bf9f4cba5d2b4be9be65..c25b7c66220d449a564e2fbff6b23d14c42bb42a 100644 (file)
@@ -213,7 +213,7 @@ netbeans_connect(char *params, int doabort)
     if (hostname != NULL && address != NULL && password != NULL)
     {
        port = atoi(address);
-       nb_channel_idx = channel_open(hostname, port, nb_channel_closed);
+       nb_channel_idx = channel_open(hostname, port, 0, nb_channel_closed);
        if (nb_channel_idx >= 0)
        {
            /* success */
index fb136718842f65a8568ae385110760bd13dd6720..db080e44ece87254f80351a6daf715cd585bc90c 100644 (file)
@@ -1123,6 +1123,29 @@ mch_setmouse(int on)
     SetConsoleMode(g_hConIn, cmodein);
 }
 
+#ifdef FEAT_CHANNEL
+    static int
+handle_channel_event(void)
+{
+    int                    ret;
+    fd_set         rfds;
+    int                    maxfd;
+
+    FD_ZERO(&rfds);
+    maxfd = channel_select_setup(-1, &rfds);
+    if (maxfd >= 0)
+    {
+       struct timeval  tv;
+
+       tv.tv_sec = 0;
+       tv.tv_usec = 0;
+       ret = select(maxfd + 1, &rfds, NULL, NULL, &tv);
+       if (ret > 0 && channel_select_check(ret, &rfds) > 0)
+           return TRUE;
+    }
+    return FALSE;
+}
+#endif
 
 /*
  * Decode a MOUSE_EVENT.  If it's a valid event, return MOUSE_LEFT,
@@ -1443,11 +1466,6 @@ WaitForChar(long msec)
     INPUT_RECORD    ir;
     DWORD          cRecords;
     WCHAR          ch, ch2;
-#ifdef FEAT_CHANNEL
-    int                    ret;
-    fd_set         rfds;
-    int                    maxfd;
-#endif
 
     if (msec > 0)
        /* Wait until the specified time has elapsed. */
@@ -1472,18 +1490,8 @@ WaitForChar(long msec)
 #endif
 
 #ifdef FEAT_CHANNEL
-       FD_ZERO(&rfds);
-       maxfd = channel_select_setup(-1, &rfds);
-       if (maxfd >= 0)
-       {
-           struct timeval  tv;
-
-           tv.tv_sec = 0;
-           tv.tv_usec = 0;
-           ret = select(maxfd + 1, &rfds, NULL, NULL, &tv);
-           if (ret > 0 && channel_select_check(ret, &rfds) > 0)
-               return TRUE;
-       }
+       if (handle_channel_event())
+           return TRUE;
 #endif
 
        if (0
index 77040a50cc2189847d87cce21826ec889a021f31..f8e4a9b9f4214f53998a3b1f516753132b1864db 100644 (file)
@@ -1,7 +1,8 @@
 /* channel.c */
 void channel_gui_register_all(void);
-int channel_open(char *hostname, int port_in, void (*close_cb)(void));
+int channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void));
 void channel_set_json_mode(int idx, int json_mode);
+void channel_set_timeout(int idx, int timeout);
 void channel_set_callback(int idx, char_u *callback);
 void channel_set_req_callback(int idx, char_u *callback, int id);
 char_u *channel_get(int idx);
index e76c524ffa61f5e676926c19b13a6fc9ceed5066..09661012106e118bdc6c301f1845739ce9dde16c 100644 (file)
@@ -57,7 +57,7 @@ func s:start_server()
   endif
   let s:port = l[0]
 
-  let handle = ch_open('localhost:' . s:port, 'json')
+  let handle = ch_open('localhost:' . s:port)
   return handle
 endfunc
 
@@ -128,7 +128,7 @@ func Test_two_channels()
   endif
   call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
 
-  let newhandle = ch_open('localhost:' . s:port, 'json')
+  let newhandle = ch_open('localhost:' . s:port)
   call assert_equal('got it', ch_sendexpr(newhandle, 'hello!'))
   call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
 
index f76e3c58ebe60687e969b37be3147e62fc94b9c9..4f8f454e41ccbe3cd684ffe66d596283882302ce 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1263,
 /**/
     1262,
 /**/