diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2010-05-29 09:44:53 +1000 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-05-29 09:44:53 +1000 |
commit | 0cda2e1f8d8222fa497f808b54a2146d60e304f5 (patch) | |
tree | 39fcfeb0ab93422c63141e8fcf5bd305a32fe7a6 | |
parent | [JOBS] Fix wait regression where it does not wait for all jobs (diff) | |
download | dash-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-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/miscbltin.c | 13 |
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; |