Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Regression with stdin handling in non-interactive mode between 5.8 and 5.8.1



> On 02 March 2022 at 22:38 Lyude Paul <lyude@xxxxxxxxxx> wrote:
> 
> 
> Hi! I'm reporting this here because after some discussion in #zsh, it was
> determined this is likely both a regression, and also isn't POSIX compliant.
> Keep in mind I don't have as clear of an understanding of what's happening
> below the hood here as I'd like, so I'm not 100% the subject line here is
> correct. I've got plenty of examples to clarify though :)
> 
> Basically, what seems to be happening is that since 5.8.1 zsh no longer seems
> to correctly handle input from stdin unless the terminal is in interactive
> mode.
> 
> Here's a simple example script that demonstrates what I mean:
> 
>    printf '%s\n' 'echo Shell is $$' sh 'echo Shell is $$' | zsh
> 
> Running on zsh 5.8 returns:
> 
>    Shell is 70
>    Shell is 71
> 
> Running on zsh 5.8.1 however, returns:
> 
>    Shell is 86396
>    Shell is 86396

Thanks for the nice simple test --- I'll try and concoct something similar
but predictable for the shell tests.

I hope it's as simple as the following.  I can't think of any optimisation
or a case where line buffering would be wrong.

pws

diff --git a/Src/input.c b/Src/input.c
index caeaff0e3..50cd2cd78 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -223,13 +223,20 @@ shingetchar(void)
 	return STOUC(*shinbufptr++);
 
     shinbufreset();
-    do {
+    for (;;) {
 	errno = 0;
-	nread = read(SHIN, shinbuffer, SHINBUFSIZE);
-    } while (nread < 0 && errno == EINTR);
-    if (nread <= 0)
+	nread = read(SHIN, shinbufendptr, 1);
+	if (nread > 0) {
+	    /* Use line buffering (POSIX requirement) */
+	    if (*shinbufendptr++ == '\n')
+		break;
+	    if (shinbufendptr == shinbuffer + SHINBUFSIZE)
+		break;
+	} else if (nread == 0 || errno != EINTR)
+	    break;
+    }
+    if (shinbufendptr == shinbuffer)
 	return -1;
-    shinbufendptr = shinbuffer + nread;
     return STOUC(*shinbufptr++);
 }




Messages sorted by: Reverse Date, Date, Thread, Author