about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBart Schaefer <schaefer@zsh.org>2024-01-28 17:14:23 -0800
committerBart Schaefer <schaefer@zsh.org>2024-01-28 17:14:23 -0800
commitd7cf4f25ebe2ec00b5e557e8202d74fa86a36062 (patch)
tree400be78a2c9f4568d6f023af2d45e3e377cb89a7
parent85545af42b8f9278136125324c37c1f88b461421 (diff)
downloadzsh-d7cf4f25ebe2ec00b5e557e8202d74fa86a36062.tar.gz
zsh-d7cf4f25ebe2ec00b5e557e8202d74fa86a36062.tar.xz
zsh-d7cf4f25ebe2ec00b5e557e8202d74fa86a36062.zip
52509: manage internals of stdio objects when performing redirections.
-rw-r--r--ChangeLog5
-rw-r--r--Src/utils.c22
-rw-r--r--configure.ac2
3 files changed, 28 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 7335590c9..6c52ccd22 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2024-01-28  Bart Schaefer  <schaefer@zsh.org>
+
+	* 52509: configure.ac, Src/utils.c: manage internals of stdio
+	objects when performing redirections.
+
 2024-01-28  Oliver Kiddle  <opk@zsh.org>
 
 	* 52500: Src/Zle/zle.h, Src/Zle/zle_refresh.c, Src/prompt.c:
diff --git a/Src/utils.c b/Src/utils.c
index 1a4f4c14b..0fda92709 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -2008,6 +2008,28 @@ redup(int x, int y)
 {
     int ret = y;
 
+#ifdef HAVE_FPURGE
+    /* Make sure buffers are cleared when changing descriptor for a
+     * FILE object.  No fflush() here because the only way anything
+     * can legitimately be left in the buffer is when an error has
+     * occurred, so attempting flush here would at best error again
+     * and at worst squirt out something unexpected.
+     */
+    if (stdout && y == fileno(stdout))
+	fpurge(stdout);
+    if (stderr && y == fileno(stderr))
+	fpurge(stderr);
+    if (shout && y == fileno(shout))
+	fpurge(shout);
+    if (xtrerr && y == fileno(xtrerr))
+	fpurge(xtrerr);
+#ifndef _IONBF
+    /* See init.c setupshin() -- stdin otherwise unbuffered */
+    if (stdin && y == fileno(stdin))
+	fpurge(stdin);
+#endif
+#endif
+
     if(x < 0)
 	zclose(y);
     else if (x != y) {
diff --git a/configure.ac b/configure.ac
index 2871dcb7c..175d90433 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1295,7 +1295,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
 	       select poll \
 	       readlink faccessx fchdir ftruncate \
 	       fstat lstat lchown fchown fchmod \
-	       fseeko ftello \
+	       fpurge fseeko ftello \
 	       mkfifo _mktemp mkstemp \
 	       waitpid wait3 \
 	       sigaction sigblock sighold sigrelse sigsetmask sigprocmask \