Patch 7.4.1249
Problem: Crash when the process a channel is connected to exits.
Solution: Use the file descriptor properly. Add a test. (Damien)
Also add a test for eval().
Files: src/channel.c, src/testdir/test_channel.py,
src/testdir/test_channel.vim
*** ../vim-7.4.1248/src/channel.c 2016-02-02 23:22:38.101181704 +0100
--- src/channel.c 2016-02-03 21:28:54.105429460 +0100
***************
*** 698,707 ****
}
else
{
! typval_T *tv = eval_expr(arg, NULL);
typval_T err_tv;
char_u *json;
if (is_eval)
{
if (tv == NULL)
--- 698,711 ----
}
else
{
! typval_T *tv;
typval_T err_tv;
char_u *json;
+ /* Don't pollute the display with errors. */
+ ++emsg_skip;
+ tv = eval_expr(arg, NULL);
+ --emsg_skip;
if (is_eval)
{
if (tv == NULL)
***************
*** 714,720 ****
channel_send(idx, json, "eval");
vim_free(json);
}
! free_tv(tv);
}
}
else if (p_verbose > 2)
--- 718,725 ----
channel_send(idx, json, "eval");
vim_free(json);
}
! if (tv != &err_tv)
! free_tv(tv);
}
}
else if (p_verbose > 2)
***************
*** 1119,1125 ****
/* Wait for up to 2 seconds.
* TODO: use timeout set on the channel. */
! if (channel_wait(channels[ch_idx].ch_fd, 2000) == FAIL)
break;
channel_read(ch_idx);
}
--- 1124,1131 ----
/* Wait for up to 2 seconds.
* TODO: use timeout set on the channel. */
! if (channels[ch_idx].ch_fd < 0
! || channel_wait(channels[ch_idx].ch_fd, 2000) == FAIL)
break;
channel_read(ch_idx);
}
*** ../vim-7.4.1248/src/testdir/test_channel.py 2016-02-03 20:13:19.721014093
+0100
--- src/testdir/test_channel.py 2016-02-03 21:11:46.544209797 +0100
***************
*** 52,58 ****
decoded = [-1, '']
# Send a response if the sequence number is positive.
- # Negative numbers are used for "eval" responses.
if decoded[0] >= 0:
if decoded[1] == 'hello!':
# simply send back a string
--- 52,57 ----
***************
*** 65,73 ****
--- 64,90 ----
print("sending: {}".format(cmd))
thesocket.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'))
+ 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'))
+ response = "ok"
+ elif decoded[1] == 'eval-result':
+ # Send back the last received eval result.
+ response = last_eval
elif decoded[1] == '!quit!':
# we're done
sys.exit(0)
+ elif decoded[1] == '!crash!':
+ # Crash!
+ 42 / 0
else:
response = "what?"
***************
*** 75,80 ****
--- 92,101 ----
print("sending: {}".format(encoded))
thesocket.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):
*** ../vim-7.4.1248/src/testdir/test_channel.vim 2016-02-03
20:22:05.127510774 +0100
--- src/testdir/test_channel.vim 2016-02-03 21:32:34.091124780 +0100
***************
*** 18,42 ****
endif
func s:start_server()
if has('win32')
silent !start cmd /c start "test_channel" py test_channel.py
else
silent !python test_channel.py&
endif
- endfunc
-
- func s:kill_server()
- if has('win32')
- call system('taskkill /IM py.exe /T /F /FI "WINDOWTITLE eq test_channel"')
- else
- call system("pkill --full test_channel.py")
- endif
- endfunc
-
- func Test_communicate()
- call delete("Xportnr")
- " The Python program writes the port number in Xportnr.
- call s:start_server()
" Wait for up to 2 seconds for the port number to be there.
let cnt = 20
--- 18,31 ----
endif
func s:start_server()
+ " The Python program writes the port number in Xportnr.
+ call delete("Xportnr")
+
if has('win32')
silent !start cmd /c start "test_channel" py test_channel.py
else
silent !python test_channel.py&
endif
" Wait for up to 2 seconds for the port number to be there.
let cnt = 20
***************
*** 57,66 ****
if len(l) == 0
" Can't make the connection, give up.
call s:kill_server()
! return
endif
let port = l[0]
let handle = ch_open('localhost:' . port, 'json')
" Simple string request and reply.
call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
--- 46,73 ----
if len(l) == 0
" Can't make the connection, give up.
call s:kill_server()
! call assert_false(1, "Can't start test_channel.py")
! return -1
endif
let port = l[0]
+
let handle = ch_open('localhost:' . port, 'json')
+ return handle
+ endfunc
+
+ func s:kill_server()
+ if has('win32')
+ call system('taskkill /IM py.exe /T /F /FI "WINDOWTITLE eq test_channel"')
+ else
+ call system("pkill --full test_channel.py")
+ endif
+ endfunc
+
+ func Test_communicate()
+ let handle = s:start_server()
+ if handle < 0
+ return
+ endif
" Simple string request and reply.
call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
***************
*** 73,80 ****
--- 80,108 ----
call assert_equal('added1', getline(line('$') - 1))
call assert_equal('added2', getline('$'))
+ " Send an eval request that works.
+ call assert_equal('ok', ch_sendexpr(handle, 'eval-works'))
+ call assert_equal([-1, 'foo123'], ch_sendexpr(handle, 'eval-result'))
+
+ " Send an eval request that fails.
+ call assert_equal('ok', ch_sendexpr(handle, 'eval-fails'))
+ call assert_equal([-2, 'ERROR'], ch_sendexpr(handle, 'eval-result'))
+
" make the server quit, can't check if this works, should not hang.
call ch_sendexpr(handle, '!quit!', 0)
call s:kill_server()
endfunc
+
+ " Test that a server crash is handled gracefully.
+ func Test_server_crash()
+ let handle = s:start_server()
+ if handle < 0
+ return
+ endif
+ call ch_sendexpr(handle, '!crash!')
+
+ " kill the server in case if failed to crash
+ sleep 10m
+ call s:kill_server()
+ endfunc
*** ../vim-7.4.1248/src/version.c 2016-02-03 20:22:05.131510733 +0100
--- src/version.c 2016-02-03 21:30:07.208663497 +0100
***************
*** 744,745 ****
--- 744,747 ----
{ /* Add new patch number below this line */
+ /**/
+ 1249,
/**/
--
hundred-and-one symptoms of being an internet addict:
122. You ask if the Netaholics Anonymous t-shirt you ordered can be
sent to you via e-mail.
/// Bram Moolenaar -- [email protected] -- 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 ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.