fix(shell): ceci n'est pas une pipe

On linux /dev/stdin is defined as a symlink to /proc/self/fd/0
This in turn is defined as a "magic" symlink which is allowed to point
to internal kernel objects which really does not have a file
name. As a glaring inconsistency, fopen("/proc/self/fd/0", "r")
works if fd was originally opened using pipe() but not using
socketpair(). As it happens UV_CREATE_PIPE does not create pipes
but creates socket pairs. These two unfortunate conditions
means that using /dev/stdin and similar does not work in
shell commands in nvim on linux. as a work around, override
libuv's descicion and create an actual pipe pair.

This change is not needed on BSD:s but done unconditionally for simplicity,
except for on windows where it is not done for stdout because of windows

fixes #35984
This commit is contained in:
bfredl
2025-10-02 10:42:50 +02:00
parent 9afd81512b
commit 5581a53437
6 changed files with 83 additions and 15 deletions

View File

@@ -196,10 +196,10 @@ describe('system()', function()
n.set_shell_powershell()
eq('ああ\n', eval([[system('Write-Output "ああ"')]]))
-- Sanity test w/ default encoding
-- * on Windows, expected to default to Western European enc
-- * on Windows, UTF-8 still works.
-- * on Linux, expected to default to UTF8
command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
eq(is_os('win') and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]]))
eq('ああ\n', eval([[system('Write-Output "ああ"')]]))
end)
it('`echo` and waits for its return', function()
@@ -548,10 +548,10 @@ describe('systemlist()', function()
n.set_shell_powershell()
eq({ is_os('win') and '\r' or '' }, eval([[systemlist('Write-Output あ')]]))
-- Sanity test w/ default encoding
-- * on Windows, expected to default to Western European enc
-- * on Windows, UTF-8 still works.
-- * on Linux, expected to default to UTF8
command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
eq({ is_os('win') and '?\r' or '' }, eval([[systemlist('Write-Output あ')]]))
eq({ is_os('win') and '\r' or '' }, eval([[systemlist('Write-Output あ')]]))
end)
end)