summaryrefslogtreecommitdiff
blob: 6e202fa2fb2467e0414df770eac56bba33be03ae (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
From da8be06c2062ea02795bcba25172369ec68848cf Mon Sep 17 00:00:00 2001
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
Date: Thu, 3 Mar 2022 19:19:35 +0000
Subject: [PATCH] 49792: Non-interative shell input is line buffered.

---
 ChangeLog            |  5 +++++
 Src/input.c          | 21 ++++++++++++++-------
 Test/A01grammar.ztst |  9 +++++++++
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8a5ad4941..cae2fc4e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2022-03-03  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 49792: Src/input.c, Test/A01grammar.ztst: Use line buffering
+	for non-interactive input.
+
 2022-02-12  dana  <dana@dana.is>
 
 	* unposted: Config/version.mk, Etc/FAQ.yo, README: Update
diff --git a/Src/input.c b/Src/input.c
index 18228b37d..caa8e23b0 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -223,13 +223,20 @@ shingetchar(void)
 	return STOUC(*shinbufptr++);
 
     shinbufreset();
-    do {
-	errno = 0;
-	nread = read(SHIN, shinbuffer, SHINBUFSIZE);
-    } while (nread < 0 && errno == EINTR);
-    if (nread <= 0)
-	return -1;
-    shinbufendptr = shinbuffer + nread;
+    for (;;) {
+       errno = 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;
     return STOUC(*shinbufptr++);
 }
 
diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst
index 1e0e9a04e..adbf5f1d9 100644
--- a/Test/A01grammar.ztst
+++ b/Test/A01grammar.ztst
@@ -932,3 +932,12 @@ F:Note that the behaviour of 'exit' inside try-list inside a function is unspeci
  $ZTST_testdir/../Src/zsh -fc '{ ( ) } always { echo foo }'
 -f:exec last command optimization inhibited for try/always
 >foo
+
+ (
+   export VALUE=first
+   print -l 'echo Value is $VALUE' 'VALUE=second sh' 'echo Value is $VALUE' |
+   $ZTST_testdir/../Src/zsh -f
+ )
+0:Non-interactive shell command input is line buffered
+>Value is first
+>Value is second
-- 
2.36.0.rc2