mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Make process substitutions work on Haiku
On Haiku:
# /bin/cat <(echo hi) # no redirection
cat: /tmp/ksh.f29pd8f: No such file or directory
Whereas this works fine:
# /bin/cat < <(echo hi) # with redirection
hi
# /opt/ast/bin/cat <(echo hi) # no redirection; use built-in
hi
Haiku does not have /dev/fd, so uses the FIFO (named pipe) fallback
mechanism. See also: c3eac977
Analysis: In the TFORK part of sh_exec(), forked branch (child),
the FIFO (sh.fifo) is unlinked immediately after opening it. This
is not a problem if the process substitution is used in combination
with a redirection, but if not, then the FIFO is passed on to the
command as a file name argument. This creates a race condition: ksh
was counting on the external 'cat' command opening the FIFO before
the child could unlink it. Whether that race is won depends on
operating system implementation details. When invoking an external
command on Haiku, the race is lost.
src/cmd/ksh93/sh/xec.c: sh_exec(): TFORK: child branch:
- Delay unlinking the FIFO until after executing the process
substitution, when we're about to exit from the child process.
This commit is contained in:
parent
de5bdd12a4
commit
f711da9081
1 changed files with 8 additions and 2 deletions
|
@ -1688,6 +1688,7 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
struct ionod *iop;
|
||||
int rewrite=0;
|
||||
#if !SHOPT_DEVFD
|
||||
char *save_sh_fifo = sh.fifo;
|
||||
if(sh.fifo_tree)
|
||||
{
|
||||
/* do not clean up process substitution FIFOs in child; parent handles this */
|
||||
|
@ -1727,8 +1728,6 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
fn = sh_open(sh.fifo,fd?O_WRONLY:O_RDONLY);
|
||||
save_errno = errno;
|
||||
timerdel(fifo_timer);
|
||||
unlink(sh.fifo);
|
||||
free(sh.fifo);
|
||||
sh.fifo = 0;
|
||||
if(fn<0)
|
||||
{
|
||||
|
@ -1803,6 +1802,13 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
path_exec(com0,com,t->com.comset);
|
||||
}
|
||||
done:
|
||||
#if !SHOPT_DEVFD
|
||||
if(save_sh_fifo)
|
||||
{
|
||||
unlink(save_sh_fifo);
|
||||
free(save_sh_fifo);
|
||||
}
|
||||
#endif
|
||||
sh_popcontext(&sh,buffp);
|
||||
if(jmpval>SH_JMPEXIT)
|
||||
siglongjmp(*sh.jmplist,jmpval);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue