aboutsummaryrefslogtreecommitdiffstats
path: root/main/busybox/0001-ash-regressions-in-process-substitution.patch
blob: 98fdba7917d492196ca85b5606593c0e0b3b99a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
From dab3c63da581f0d3d58e3ea1a620474eb5dad0ee Mon Sep 17 00:00:00 2001
From: Ron Yorston <rmy@pobox.com>
Date: Mon, 30 Aug 2021 20:31:42 +0100
Subject: [PATCH] ash: regressions in process substitution

Stacy Harper reports that this script:

   test() { . /tmp/bb_test; }
   echo "export TEST=foo" >/tmp/bb_test
   test 2>/dev/null
   echo "$TEST"

correctly prints 'foo' in BusyBox 1.33 but hangs in 1.34.

Bisection suggested the problem was caused by commit a1b0d3856 (ash: add
process substitution in bash-compatibility mode).  Removing the call to
unwindredir() in cmdloop() introduced in that commit makes the script
work again.

Additionally, these examples of process substitution:

   while true; do cat <(echo hi); done
   f() { while true; do cat <(echo hi); done }
   f

result in running out of file descriptors.  This is a regression from
v5 of the process substitution patch caused by changes to evalcommand()
not being transferred to v6.

function                                             old     new   delta
static.pushredir                                       -      99     +99
evalcommand                                         1729    1750     +21
exitreset                                             69      86     +17
cmdloop                                              372     365      -7
unwindredir                                           28       -     -28
pushredir                                            112       -    -112
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 2/1 up/down: 137/-147)          Total: -10 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
---
 shell/ash.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index b5947147a..53c140930 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -10278,6 +10278,9 @@ evalcommand(union node *cmd, int flags)
 
 	/* First expand the arguments. */
 	TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
+#if BASH_PROCESS_SUBST
+	redir_stop = redirlist;
+#endif
 	file_stop = g_parsefile;
 	back_exitstatus = 0;
 
@@ -10356,7 +10359,11 @@ evalcommand(union node *cmd, int flags)
 		lastarg = nargv[-1];
 
 	expredir(cmd->ncmd.redirect);
+#if !BASH_PROCESS_SUBST
 	redir_stop = pushredir(cmd->ncmd.redirect);
+#else
+	pushredir(cmd->ncmd.redirect);
+#endif
 	preverrout_fd = 2;
 	if (BASH_XTRACEFD && xflag) {
 		/* NB: bash closes fd == $BASH_XTRACEFD when it is changed.
@@ -13476,9 +13483,6 @@ cmdloop(int top)
 #if JOBS
 		if (doing_jobctl)
 			showjobs(SHOW_CHANGED|SHOW_STDERR);
-#endif
-#if BASH_PROCESS_SUBST
-		unwindredir(NULL);
 #endif
 		inter = 0;
 		if (iflag && top) {