summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-02-03 23:25:07 +0100
committerBram Moolenaar <Bram@vim.org>2016-02-03 23:25:07 +0100
commit3b05b135e3ee4cfd59983fd63461e8f7642c1713 (patch)
tree05d2d71092c388672c46c2e0ed09ed275c3aa5dc
parent608a8919cae982cb38e38725a843df47b234dae6 (diff)
patch 7.4.1254v7.4.1254
Problem: Opening a second channel causes a crash. (Ken Takata) Solution: Don't re-allocate the array with channels.
-rw-r--r--src/channel.c21
-rw-r--r--src/testdir/test_channel.py14
-rw-r--r--src/testdir/test_channel.vim24
-rw-r--r--src/version.c2
4 files changed, 40 insertions, 21 deletions
diff --git a/src/channel.c b/src/channel.c
index 2e5965bc7b..9e15fe4551 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -133,22 +133,25 @@ FILE *debugfd = NULL;
add_channel(void)
{
int idx;
- channel_T *new_channels;
channel_T *ch;
if (channels != NULL)
+ {
for (idx = 0; idx < channel_count; ++idx)
if (channels[idx].ch_fd < 0)
/* re-use a closed channel slot */
return idx;
- if (channel_count == MAX_OPEN_CHANNELS)
- return -1;
- new_channels = (channel_T *)alloc(sizeof(channel_T) * (channel_count + 1));
- if (new_channels == NULL)
- return -1;
- if (channels != NULL)
- mch_memmove(new_channels, channels, sizeof(channel_T) * channel_count);
- channels = new_channels;
+ if (channel_count == MAX_OPEN_CHANNELS)
+ return -1;
+ }
+ else
+ {
+ channels = (channel_T *)alloc((int)sizeof(channel_T)
+ * MAX_OPEN_CHANNELS);
+ if (channels == NULL)
+ return -1;
+ }
+
ch = &channels[channel_count];
(void)vim_memset(ch, 0, sizeof(channel_T));
diff --git a/src/testdir/test_channel.py b/src/testdir/test_channel.py
index 3133c2f408..f1d774fd11 100644
--- a/src/testdir/test_channel.py
+++ b/src/testdir/test_channel.py
@@ -24,14 +24,10 @@ except ImportError:
# Python 2
import SocketServer as socketserver
-thesocket = None
-
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
print("=== socket opened ===")
- global thesocket
- thesocket = self.request
while True:
try:
received = self.request.recv(4096).decode('utf-8')
@@ -77,19 +73,19 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
cmd = '["ex","call append(\\"$\\",\\"added1\\")"]'
cmd += '["ex","call append(\\"$\\",\\"added2\\")"]'
print("sending: {}".format(cmd))
- thesocket.sendall(cmd.encode('utf-8'))
+ self.request.sendall(cmd.encode('utf-8'))
response = "ok"
elif decoded[1] == 'eval-works':
# Send an eval request. We ignore the response.
cmd = '["eval","\\"foo\\" . 123", -1]'
print("sending: {}".format(cmd))
- thesocket.sendall(cmd.encode('utf-8'))
+ self.request.sendall(cmd.encode('utf-8'))
response = "ok"
elif decoded[1] == 'eval-fails':
# Send an eval request that will fail.
cmd = '["eval","xxx", -2]'
print("sending: {}".format(cmd))
- thesocket.sendall(cmd.encode('utf-8'))
+ self.request.sendall(cmd.encode('utf-8'))
response = "ok"
elif decoded[1] == 'eval-result':
# Send back the last received eval result.
@@ -105,14 +101,12 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
encoded = json.dumps([decoded[0], response])
print("sending: {}".format(encoded))
- thesocket.sendall(encoded.encode('utf-8'))
+ self.request.sendall(encoded.encode('utf-8'))
# Negative numbers are used for "eval" responses.
elif decoded[0] < 0:
last_eval = decoded
- thesocket = None
-
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index de64188e20..b416520e45 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -17,6 +17,8 @@ else
finish
endif
+let s:port = -1
+
func s:start_server()
" The Python program writes the port number in Xportnr.
call delete("Xportnr")
@@ -49,9 +51,9 @@ func s:start_server()
call assert_false(1, "Can't start test_channel.py")
return -1
endif
- let port = l[0]
+ let s:port = l[0]
- let handle = ch_open('localhost:' . port, 'json')
+ let handle = ch_open('localhost:' . s:port, 'json')
return handle
endfunc
@@ -94,6 +96,24 @@ func Test_communicate()
call s:kill_server()
endfunc
+" Test that we can open two channels.
+func Test_two_channels()
+ let handle = s:start_server()
+ if handle < 0
+ return
+ endif
+ call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
+
+ let newhandle = ch_open('localhost:' . s:port, 'json')
+ call assert_equal('got it', ch_sendexpr(newhandle, 'hello!'))
+ call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
+
+ call ch_close(handle)
+ call assert_equal('got it', ch_sendexpr(newhandle, 'hello!'))
+
+ call s:kill_server()
+endfunc
+
" Test that a server crash is handled gracefully.
func Test_server_crash()
let handle = s:start_server()
diff --git a/src/version.c b/src/version.c
index 2d61d4f26c..6a86d6a36e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1254,
+/**/
1253,
/**/
1252,