summaryrefslogtreecommitdiff
path: root/Src
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 /Src
parent85545af42b8f9278136125324c37c1f88b461421 (diff)
downloadzsh-d7cf4f25ebe2ec00b5e557e8202d74fa86a36062.tar.gz
zsh-d7cf4f25ebe2ec00b5e557e8202d74fa86a36062.zip
52509: manage internals of stdio objects when performing redirections.
Diffstat (limited to 'Src')
-rw-r--r--Src/utils.c22
1 files changed, 22 insertions, 0 deletions
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) {