mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 04:42:03 +00:00
fix(process): avoid unexpected behavior when PTY chdir failed (#37614)
Problem: Unexpected behavior after PTY child process fails to chdir(),
as it then thinks it's the parent process.
Solution: Exit the child process instead of returning.
This commit is contained in:
@@ -263,7 +263,7 @@ void pty_proc_teardown(Loop *loop)
|
||||
}
|
||||
|
||||
static void init_child(PtyProc *ptyproc)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NORETURN
|
||||
{
|
||||
#if defined(HAVE__NSGETENVIRON)
|
||||
# define environ (*_NSGetEnviron())
|
||||
@@ -285,7 +285,7 @@ static void init_child(PtyProc *ptyproc)
|
||||
// Don't use os_chdir() as that may buffer UI events unnecessarily.
|
||||
if (proc->cwd && (err = uv_chdir(proc->cwd)) != 0) {
|
||||
ELOG("chdir(%s) failed: %s", proc->cwd, uv_strerror(err));
|
||||
return;
|
||||
_exit(122);
|
||||
}
|
||||
|
||||
const char *prog = proc_get_exepath(proc);
|
||||
|
||||
@@ -297,18 +297,42 @@ describe('jobs', function()
|
||||
end)
|
||||
|
||||
it('error on non-executable `cwd`', function()
|
||||
if is_os('win') then
|
||||
return -- Not applicable for Windows.
|
||||
end
|
||||
skip(is_os('win'), 'N/A for Windows')
|
||||
|
||||
local dir = 'Xtest_not_executable_dir'
|
||||
mkdir(dir)
|
||||
finally(function()
|
||||
rmdir(dir)
|
||||
end)
|
||||
fn.setfperm(dir, 'rw-------')
|
||||
|
||||
matches(
|
||||
'^Vim%(call%):E903: Process failed to start: permission denied: .*',
|
||||
pcall_err(command, "call jobstart(['pwd'], {'cwd': '" .. dir .. "'})")
|
||||
pcall_err(command, ("call jobstart(['pwd'], {'cwd': '%s'})"):format(dir))
|
||||
)
|
||||
rmdir(dir)
|
||||
end)
|
||||
|
||||
it('error log and exit status 122 on non-executable `cwd`', function()
|
||||
skip(is_os('win'), 'N/A for Windows')
|
||||
|
||||
local logfile = 'Xchdir_fail_log'
|
||||
clear({ env = { NVIM_LOG_FILE = logfile } })
|
||||
|
||||
local dir = 'Xtest_not_executable_dir'
|
||||
mkdir(dir)
|
||||
finally(function()
|
||||
rmdir(dir)
|
||||
n.check_close()
|
||||
os.remove(logfile)
|
||||
end)
|
||||
fn.setfperm(dir, 'rw-------')
|
||||
|
||||
n.exec(([[
|
||||
let s:chan = jobstart(['pwd'], {'cwd': '%s', 'pty': v:true})
|
||||
let g:status = jobwait([s:chan], 1000)[0]
|
||||
]]):format(dir))
|
||||
eq(122, eval('g:status'))
|
||||
t.assert_log(('chdir%%(%s%%) failed: permission denied'):format(dir), logfile, 100)
|
||||
end)
|
||||
|
||||
it('returns 0 when it fails to start', function()
|
||||
|
||||
Reference in New Issue
Block a user