summaryrefslogtreecommitdiffstats
path: root/bin/sh/miscbltin.c
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2013-05-03 15:28:31 +0000
committerjilles <jilles@FreeBSD.org>2013-05-03 15:28:31 +0000
commit3f27c6916965a63b42f0a8f1dc9c95cd75faa4fa (patch)
tree4595e56573a1621805ce3c9493340d4c3a9ce61c /bin/sh/miscbltin.c
parentcc9f388839c014f29ebe7586e40ad11d1683c173 (diff)
downloadFreeBSD-src-3f27c6916965a63b42f0a8f1dc9c95cd75faa4fa.zip
FreeBSD-src-3f27c6916965a63b42f0a8f1dc9c95cd75faa4fa.tar.gz
sh: Improve error handling in read builtin:
* If read -t times out, return status as if interrupted by SIGALRM (formerly 1). * If a trapped signal interrupts read, return status 128+sig (formerly 1). * If [EINTR] occurs but there is no trap, retry the read (for example because of a SIGWINCH in interactive mode). * If a read error occurs, write an error message and return status 2. As before, a variable assignment error returns 2 and discards the remaining data read.
Diffstat (limited to 'bin/sh/miscbltin.c')
-rw-r--r--bin/sh/miscbltin.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c
index b81cc82..2ecd4f2 100644
--- a/bin/sh/miscbltin.c
+++ b/bin/sh/miscbltin.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include "error.h"
#include "mystring.h"
#include "syntax.h"
+#include "trap.h"
#undef eflag
@@ -102,6 +103,8 @@ readcmd(int argc __unused, char **argv __unused)
struct timeval tv;
char *tvptr;
fd_set ifds;
+ ssize_t nread;
+ int sig;
rflag = 0;
prompt = NULL;
@@ -156,8 +159,10 @@ readcmd(int argc __unused, char **argv __unused)
/*
* If there's nothing ready, return an error.
*/
- if (status <= 0)
- return(1);
+ if (status <= 0) {
+ sig = pendingsig;
+ return (128 + (sig != 0 ? sig : SIGALRM));
+ }
}
status = 0;
@@ -165,7 +170,19 @@ readcmd(int argc __unused, char **argv __unused)
backslash = 0;
STARTSTACKSTR(p);
for (;;) {
- if (read(STDIN_FILENO, &c, 1) != 1) {
+ nread = read(STDIN_FILENO, &c, 1);
+ if (nread == -1) {
+ if (errno == EINTR) {
+ sig = pendingsig;
+ if (sig == 0)
+ continue;
+ status = 128 + sig;
+ break;
+ }
+ warning("read error: %s", strerror(errno));
+ status = 2;
+ break;
+ } else if (nread != 1) {
status = 1;
break;
}
OpenPOWER on IntegriCloud