@@ -42,19 +42,20 @@
* This file implements the input routines used by the parser.
*/
-#include "eval.h"
-#include "shell.h"
-#include "redir.h"
-#include "syntax.h"
-#include "input.h"
-#include "output.h"
-#include "options.h"
-#include "memalloc.h"
-#include "error.h"
#include "alias.h"
-#include "parser.h"
+#include "error.h"
+#include "eval.h"
+#include "input.h"
#include "main.h"
+#include "memalloc.h"
#include "myhistedit.h"
+#include "options.h"
+#include "output.h"
+#include "parser.h"
+#include "redir.h"
+#include "shell.h"
+#include "syntax.h"
+#include "trap.h"
#define IBUFSIZ (BUFSIZ + PUNGETC_MAX + 1)
@@ -258,7 +259,7 @@ retry:
}
if (nr < 0) {
- if (errno == EINTR)
+ if (errno == EINTR && !(basepf.prev && pending_sig))
goto retry;
}
return nr;
@@ -522,6 +523,13 @@ pushfile(void)
parsefile = pf;
}
+void pushstdin(void)
+{
+ INTOFF;
+ basepf.prev = parsefile;
+ parsefile = &basepf;
+ INTON;
+}
void
popfile(void)
@@ -529,6 +537,11 @@ popfile(void)
struct parsefile *pf = parsefile;
INTOFF;
+ parsefile = pf->prev;
+ pf->prev = NULL;
+ if (pf == &basepf)
+ goto out;
+
if (pf->fd >= 0)
close(pf->fd);
if (pf->buf)
@@ -539,15 +552,16 @@ popfile(void)
popstring();
freestrings(parsefile->spfree);
}
- parsefile = pf->prev;
ckfree(pf);
+
+out:
INTON;
}
-void unwindfiles(struct parsefile *stop)
+void __attribute__((noinline)) unwindfiles(struct parsefile *stop)
{
- while (parsefile != stop)
+ while (basepf.prev || parsefile != stop)
popfile();
}
@@ -109,6 +109,7 @@ void pungetn(int);
void pushstring(char *, void *);
int setinputfile(const char *, int);
void setinputstring(char *);
+void pushstdin(void);
void popfile(void);
void unwindfiles(struct parsefile *);
void popallfiles(void);
@@ -46,18 +46,20 @@
#include <ctype.h>
#include <inttypes.h>
-#include "shell.h"
-#include "options.h"
-#include "var.h"
-#include "output.h"
-#include "memalloc.h"
#include "error.h"
+#include "expand.h"
+#include "input.h"
+#include "memalloc.h"
#include "miscbltin.h"
#include "mystring.h"
#include "main.h"
-#include "expand.h"
+#include "options.h"
+#include "output.h"
#include "parser.h"
+#include "shell.h"
+#include "syntax.h"
#include "trap.h"
+#include "var.h"
#undef rflag
@@ -115,14 +117,13 @@ readcmd_handle_line(char *s, int ac, char **ap)
int
readcmd(int argc, char **argv)
{
- char **ap;
- char c;
- int rflag;
char *prompt;
- char *p;
int startloc;
int newloc;
int status;
+ char **ap;
+ int rflag;
+ char *p;
int i;
rflag = 0;
@@ -145,19 +146,17 @@ readcmd(int argc, char **argv)
status = 0;
STARTSTACKSTR(p);
+ pushstdin();
+
goto start;
for (;;) {
- switch (read(0, &c, 1)) {
- case 1:
- break;
- default:
- if (errno == EINTR && !pending_sig)
- continue;
- /* fall through */
- case 0:
+ int c;
+
+ c = pgetc();
+ if (c == PEOF) {
status = 1;
- goto out;
+ break;
}
if (c == '\0')
continue;
@@ -186,7 +185,7 @@ start:
newloc = startloc - 1;
}
}
-out:
+ popfile();
recordregion(startloc, p - (char *)stackblock(), 0);
STACKSTRNUL(p);
readcmd_handle_line(p + 1, argc - (ap - argv), ap);
Use pgetc instead of read(2) in read(1). This allows any future buffering in the input layer to be used by read(1). This also allows read(1) to call helpers in the parser that may use the input layer. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> --- src/input.c | 42 ++++++++++++++++++++++++++++-------------- src/input.h | 1 + src/miscbltin.c | 39 +++++++++++++++++++-------------------- 3 files changed, 48 insertions(+), 34 deletions(-)