+52
-5
lines changedFilter options
+52
-5
lines changed Original file line number Diff line number Diff line change
@@ -1140,6 +1140,7 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err)
1140
1140
TerminalOptions topts;
1141
1141
Channel *chan = channel_alloc(kChannelStreamInternal);
1142
1142
chan->stream.internal.cb = cb;
1143
+
chan->stream.internal.closed = false;
1143
1144
topts.data = chan;
1144
1145
// NB: overridden in terminal_check_size if a window is already
1145
1146
// displaying the buffer
Original file line number Diff line number Diff line change
@@ -138,8 +138,14 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
138
138
*error = (const char *)e_invstream;
139
139
return false;
140
140
}
141
-
api_free_luaref(chan->stream.internal.cb);
142
-
chan->stream.internal.cb = LUA_NOREF;
141
+
if (chan->term) {
142
+
api_free_luaref(chan->stream.internal.cb);
143
+
chan->stream.internal.cb = LUA_NOREF;
144
+
chan->stream.internal.closed = true;
145
+
terminal_close(chan->term, 0);
146
+
} else {
147
+
channel_decref(chan);
148
+
}
143
149
break;
144
150
145
151
default:
@@ -536,7 +542,11 @@ size_t channel_send(uint64_t id, char *data, size_t len, bool data_owned, const
536
542
}
537
543
538
544
if (chan->streamtype == kChannelStreamInternal) {
539
-
if (!chan->term) {
545
+
if (chan->is_rpc) {
546
+
*error = _("Can't send raw data to rpc channel");
547
+
goto retfree;
548
+
}
549
+
if (!chan->term || chan->stream.internal.closed) {
540
550
*error = _("Can't send data to closed stream");
541
551
goto retfree;
542
552
}
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@ typedef struct {
44
44
45
45
typedef struct {
46
46
LuaRef cb;
47
+
bool closed;
47
48
} InternalState;
48
49
49
50
typedef struct {
Original file line number Diff line number Diff line change
@@ -317,10 +317,14 @@ void terminal_close(Terminal *term, int status)
317
317
term->opts.close_cb(term->opts.data);
318
318
}
319
319
} else if (!only_destroy) {
320
-
// This was called by channel_process_exit_cb() not in process_teardown().
320
+
// Associated channel has been closed and the editor is not exiting.
321
321
// Do not call the close callback now. Wait for the user to press a key.
322
322
char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
323
-
snprintf(msg, sizeof msg, "\r\n[Process exited %d]", status);
323
+
if (((Channel *)term->opts.data)->streamtype == kChannelStreamInternal) {
324
+
snprintf(msg, sizeof msg, "\r\n[Terminal closed]");
325
+
} else {
326
+
snprintf(msg, sizeof msg, "\r\n[Process exited %d]", status);
327
+
}
324
328
terminal_receive(term, msg, strlen(msg));
325
329
}
326
330
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@ local nvim_prog = helpers.nvim_prog
10
10
local is_os = helpers.is_os
11
11
local retry = helpers.retry
12
12
local expect_twostreams = helpers.expect_twostreams
13
+
local assert_alive = helpers.assert_alive
14
+
local pcall_err = helpers.pcall_err
13
15
14
16
describe('channels', function()
15
17
local init = [[
@@ -314,3 +316,22 @@ describe('channels', function()
314
316
eq({"notification", "exit", {id, 1, {''}}}, next_msg())
315
317
end)
316
318
end)
319
+
320
+
describe('loopback', function()
321
+
before_each(function()
322
+
clear()
323
+
command("let chan = sockconnect('pipe', v:servername, {'rpc': v:true})")
324
+
end)
325
+
326
+
it('does not crash when sending raw data', function()
327
+
eq("Vim(call):Can't send raw data to rpc channel",
328
+
pcall_err(command, "call chansend(chan, 'test')"))
329
+
assert_alive()
330
+
end)
331
+
332
+
it('are released when closed', function()
333
+
local chans = eval('len(nvim_list_chans())')
334
+
command('call chanclose(chan)')
335
+
eq(chans - 1, eval('len(nvim_list_chans())'))
336
+
end)
337
+
end)
Original file line number Diff line number Diff line change
@@ -43,3 +43,13 @@ describe('associated channel is closed and later freed for terminal', function()
43
43
eq("Vim(call):E900: Invalid channel id", pcall_err(command, [[call chansend(id, 'test')]]))
44
44
end)
45
45
end)
46
+
47
+
describe('channel created by nvim_open_term', function()
48
+
before_each(clear)
49
+
50
+
it('can close', function()
51
+
command('let id = nvim_open_term(0, {})')
52
+
eq("Vim(call):Can't send data to closed stream",
53
+
pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]]))
54
+
end)
55
+
end)
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4