mirror of
https://github.com/neovim/neovim.git
synced 2026-04-26 09:14:15 +00:00
fix(channel): crash on exit after closing v:stderr channel (#38754)
Problem: Crash on exit after closing v:stderr channel when piping
to stdin.
Solution: Reopen stderr as /dev/null or NUL instead of closing it.
This also avoids writing to an related file if one is opened
after closing v:stderr.
(cherry picked from commit e20c4ea966)
This commit is contained in:
committed by
github-actions[bot]
parent
58cc2fdc5f
commit
6ef5f59be6
@@ -167,7 +167,13 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
|||||||
chan->stream.err.closed = true;
|
chan->stream.err.closed = true;
|
||||||
// Don't close on exit, in case late error messages
|
// Don't close on exit, in case late error messages
|
||||||
if (!exiting) {
|
if (!exiting) {
|
||||||
fclose(stderr);
|
// Don't close the file descriptor, as that may cause later writes to stderr
|
||||||
|
// to go to an unrelated file. Redirect it to NUL or /dev/null instead.
|
||||||
|
#ifdef MSWIN
|
||||||
|
freopen("NUL:", "w", stderr);
|
||||||
|
#else
|
||||||
|
freopen("/dev/null", "w", stderr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
channel_decref(chan);
|
channel_decref(chan);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,12 +119,12 @@ describe(':cquit', function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('no crash after :quit non-last window during exit', function()
|
describe('when piping to stdin, no crash during exit', function()
|
||||||
before_each(function()
|
before_each(function()
|
||||||
n.clear()
|
n.clear()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('in vim.schedule() callback and when piping to stdin #14379', function()
|
it('after :quit non-last window in vim.schedule() callback #14379', function()
|
||||||
n.fn.system({
|
n.fn.system({
|
||||||
n.nvim_prog,
|
n.nvim_prog,
|
||||||
'-es',
|
'-es',
|
||||||
@@ -135,7 +135,7 @@ describe('no crash after :quit non-last window during exit', function()
|
|||||||
eq(0, n.api.nvim_get_vvar('shell_error'))
|
eq(0, n.api.nvim_get_vvar('shell_error'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('in vim.defer_fn() callback and when piping to stdin #14379', function()
|
it('after :quit non-last window in vim.defer_fn() callback #14379', function()
|
||||||
n.fn.system({
|
n.fn.system({
|
||||||
n.nvim_prog,
|
n.nvim_prog,
|
||||||
'-es',
|
'-es',
|
||||||
@@ -145,4 +145,15 @@ describe('no crash after :quit non-last window during exit', function()
|
|||||||
}, '')
|
}, '')
|
||||||
eq(0, n.api.nvim_get_vvar('shell_error'))
|
eq(0, n.api.nvim_get_vvar('shell_error'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('after closing v:stderr channel', function()
|
||||||
|
n.fn.system({
|
||||||
|
n.nvim_prog,
|
||||||
|
'-es',
|
||||||
|
'--cmd',
|
||||||
|
'call chanclose(v:stderr)',
|
||||||
|
'+quit',
|
||||||
|
}, '')
|
||||||
|
eq(0, n.api.nvim_get_vvar('shell_error'))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user