ksh: Process substitution as file name to redirection is not compiled by shcomp
The commands within a process substitution (<(
…)
an >(
…)
) are simply not included in parse trees dumped by shcomp. This can be verified with a command like hexdump -C
. As a result, process substitutions don’t work when running a bytecode-compiled shell script.
The bug/omission is likely to be somewhere in src/cmd/ksh93/sh/tdump.c
which is the code for dumping a parse tree into a file. It may be that src/cmd/ksh93/sh/trestore.c
also needs changing.
This problem is also in 93u+, 93v- and ksh2020. Another one of those amazing bugs that have been there for decades. shcomp is basically not usable before this is fixed, unless you know the script does not contain any process substitutions.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 17
Commits related to this issue
- Fix the <>; redirection operator in -c scripts This bug was first reported at https://github.com/att/ast/issues/9. The <>; operator doesn't work correctly if it's used as the last command of a -c sc... — committed to JohnoKing/ksh by JohnoKing 3 years ago
- To workaround another segfault caused by #165, avoid procsubs here also — committed to JohnoKing/ksh by JohnoKing 3 years ago
- Fix <>; redirection for final command exec optimization (#277) The <>; operator doesn't work correctly if it's used as the last command of a -c script. Reproducer: $ echo test > a; ksh -c 'echo x... — committed to ksh93/ksh by JohnoKing 3 years ago
- shcomp: fix redirection with process substitution The commands within a process substitution used as an argument to a redirection (e.g. < <(...) or > >(...)) are simply not included in parse trees du... — committed to ksh93/ksh by McDutchie 3 years ago
New patch:
Now it does seem to be detected correctly:
This is minor, but error messages should be followed by
UNREACHABLE()
when they don’t return:On another note, I tested the patch and it causes the io.sh regression tests to fail under shcomp:
I’ve studied the code in io.c for executing process substitutions with redirections: https://github.com/ksh93/ksh/blob/6b9703ffdd9a71c3fb7418ba7744fd734e39f454/src/cmd/ksh93/sh/io.c#L1176-L1187
So,
iop->ioname
may start with ‘\n\0’ and appear to be a string containing a newline, but it’s actually a pointer to the parse tree for the process substitution and should be handled with a typecast tostruct argnod*
.Based on that code, I’ve come up with the following provisional patch. It needs an extra hack to avoid the segfault in
p_arg()
. It does cause the command to be included in the shcomp output. Unfortunately, when trying to run it, ksh segfaults.Note that the
sh_argprocsub()
call is not included because that causes a file name like/dev/fd/4
to be included in the shcomp output instead of the process substitution’s parse tree.This test script now compiles like this:
Backtrace of the crash:
So it crashes here, in
strchr()
: https://github.com/ksh93/ksh/blob/6b9703ffdd9a71c3fb7418ba7744fd734e39f454/src/cmd/ksh93/sh/xec.c#L1224That’s as far as I got for now, I hope this is some progress.