summary refs log tree commit diff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2010-05-29 09:44:53 +1000
committerHerbert Xu <herbert@gondor.apana.org.au>2010-05-29 09:44:53 +1000
commit0cda2e1f8d8222fa497f808b54a2146d60e304f5 (patch)
tree39fcfeb0ab93422c63141e8fcf5bd305a32fe7a6
parent[JOBS] Fix wait regression where it does not wait for all jobs (diff)
downloaddash-0cda2e1f8d8222fa497f808b54a2146d60e304f5.tar.gz
dash-0cda2e1f8d8222fa497f808b54a2146d60e304f5.zip
[BUILTIN] Continue after EINTR in read(1) with no pending signals
The recent introduction of SIGCHLD trapping broke read(1) as
each SIGCHLD may cause read(1) to return prematurely.  Now if
we did have a trap for SIGCHLD read(1) should actually do this.
However, returning when SIGCHLD isn't trapped is wrong.

This patch fixes this by checking for EINTR and pendingsigs in
read(1).

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to '')
-rw-r--r--ChangeLog4
-rw-r--r--src/miscbltin.c13
2 files changed, 15 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 54d2972..5a11a8c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-05-29  Herbert Xu <herbert@gondor.apana.org.au>
+
+	* Continue after EINTR in read(1) with no pending signals.
+
 2010-05-27  Jilles Tjoelker <jilles@stack.nl>
 
 	* Force fork if any trap is set, not just on EXIT.
diff --git a/src/miscbltin.c b/src/miscbltin.c
index 046f2f2..5ab1648 100644
--- a/src/miscbltin.c
+++ b/src/miscbltin.c
@@ -57,6 +57,7 @@
 #include "main.h"
 #include "expand.h"
 #include "parser.h"
+#include "trap.h"
 
 #undef rflag
 
@@ -158,9 +159,16 @@ readcmd(int argc, char **argv)
 	backslash = 0;
 	STARTSTACKSTR(p);
 	for (;;) {
-		if (read(0, &c, 1) != 1) {
-			status = 1;
+		switch (read(0, &c, 1)) {
+		case 1:
 			break;
+		default:
+			if (errno == EINTR && !pendingsigs)
+				continue;
+				/* fall through */
+		case 0:
+			status = 1;
+			goto out;
 		}
 		if (c == '\0')
 			continue;
@@ -181,6 +189,7 @@ put:
 resetbs:
 		backslash = 0;
 	}
+out:
 	STACKSTRNUL(p);
 	readcmd_handle_line(stackblock(), ap, p + 1 - (char *)stackblock());
 	return status;