about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStephane Chazelas <stephane@chazelas.org>2024-02-18 18:52:50 +0000
committerStephane Chazelas <stephane@chazelas.org>2024-02-18 18:56:39 +0000
commitf1e7481b8690a6ef71a83853f05645cb774778ab (patch)
tree1e6c56c47891a6f412efda764d1e5b53279ae972
parentc2cf21c8f012db611bab1c92ee68e8af9d09fb65 (diff)
downloadzsh-f1e7481b8690a6ef71a83853f05645cb774778ab.tar.gz
zsh-f1e7481b8690a6ef71a83853f05645cb774778ab.tar.xz
zsh-f1e7481b8690a6ef71a83853f05645cb774778ab.zip
45837: fix process group restoration upon exit
-rw-r--r--ChangeLog6
-rw-r--r--Src/exec.c2
-rw-r--r--Src/init.c13
-rw-r--r--Src/options.c7
4 files changed, 19 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 9afb3e41c..cebc7c6ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2024-02-18  Stephane Chazelas  <stephane@chazelas.org>
 
+	* 45837: Src/exec.c, Src/init.c, Src/options.c: fix issue whereby
+	original process group is not restored properly upon exit when
+	exec {var} redirs are used or MONITOR is temporarily disabled.
+
+2024-02-18  Stephane Chazelas  <stephane@chazelas.org>
+
 	* 52515: Src/exec.c (+ tests in 52527) avoid sh errors when
 	  running shebang-less scripts with paths starting with - or +
 
diff --git a/Src/exec.c b/Src/exec.c
index 9c8bbb458..1565cb13e 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -3768,7 +3768,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 		addfd(forked, save, mfds, fn->fd1, fil, 0, fn->varid);
 		/* If this is 'exec < file', read from stdin, *
 		 * not terminal, unless `file' is a terminal. */
-		if (nullexec == 1 && fn->fd1 == 0 &&
+		if (nullexec == 1 && fn->fd1 == 0 && !fn->varid &&
 		    isset(SHINSTDIN) && interact && !zleactive)
 		    init_io(NULL);
 		break;
diff --git a/Src/init.c b/Src/init.c
index 799ad19f6..83b79d3d4 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -700,11 +700,14 @@ init_io(char *cmd)
      * process group leader.
      */
     mypid = (zlong)getpid();
-    if (opts[MONITOR] && (SHTTY != -1)) {
-	origpgrp = GETPGRP();
-        acquire_pgrp(); /* might also clear opts[MONITOR] */
-    } else
-	opts[MONITOR] = 0;
+    if (opts[MONITOR]) {
+	if (SHTTY == -1)
+	    opts[MONITOR] = 0;
+	else if (!origpgrp) {
+	    origpgrp = GETPGRP();
+	    acquire_pgrp(); /* might also clear opts[MONITOR] */
+	}
+    }
 #else
     opts[MONITOR] = 0;
 #endif
diff --git a/Src/options.c b/Src/options.c
index a994b563e..a0e1aa024 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -881,11 +881,12 @@ dosetopt(int optno, int value, int force, char *new_opts)
     } else if (!force && optno == MONITOR && value) {
 	if (new_opts[optno] == value)
 	    return 0;
-	if (SHTTY != -1) {
+	if (SHTTY == -1)
+	    return -1;
+	if (!origpgrp) {
 	    origpgrp = GETPGRP();
 	    acquire_pgrp();
-	} else
-	    return -1;
+	}
 #else
     } else if(optno == MONITOR && value) {
 	    return -1;