summaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c120
1 files changed, 94 insertions, 26 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 334dc22..f852b26 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -5,6 +5,10 @@
* Copyright (c) 1989, 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
+ * Copyright (c) 1997-2003 Herbert Xu <herbert@debian.org>
+ * was re-ported from NetBSD and debianized.
+ *
+ *
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
@@ -22,14 +26,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * This version of ash is adapted from the source in Debian's ash 0.3.8-5
- * package.
- * Maintainer Herbert Xu <herbert@debian.org> (C) 1997-2002
*
* Modified by Vladimir Oleynik <dzo@simtreas.ru> to be used in busybox
*
*
- * Original copyright notice is retained at the end of this file.
+ * Original BSD copyright notice is retained at the end of this file.
*/
/*
@@ -1485,8 +1486,11 @@ static const char defpathvar[] =
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
#ifdef IFS_BROKEN
static const char defifsvar[] = "IFS= \t\n";
-#endif
+#define defifs (defifsvar + 4)
+#else
static const char defifs[] = " \t\n";
+#endif
+
static struct var varinit[] = {
#ifdef IFS_BROKEN
@@ -9848,6 +9852,89 @@ out:
* have parseword (readtoken1?) handle both words and redirection.]
*/
+#define NEW_xxreadtoken
+#ifdef NEW_xxreadtoken
+
+/* singles must be first! */
+static const char xxreadtoken_chars[7] = { '\n', '(', ')', '&', '|', ';', 0 };
+
+static const char xxreadtoken_tokens[] = {
+ TNL, TLP, TRP, /* only single occurrence allowed */
+ TBACKGND, TPIPE, TSEMI, /* if single occurrence */
+ TEOF, /* corresponds to trailing nul */
+ TAND, TOR, TENDCASE, /* if double occurrence */
+};
+
+#define xxreadtoken_doubles \
+ (sizeof(xxreadtoken_tokens) - sizeof(xxreadtoken_chars))
+#define xxreadtoken_singles \
+ (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1)
+
+static int xxreadtoken()
+{
+ int c;
+
+ if (tokpushback) {
+ tokpushback = 0;
+ return lasttoken;
+ }
+ if (needprompt) {
+ setprompt(2);
+ needprompt = 0;
+ }
+ startlinno = plinno;
+ for (;;) { /* until token or start of word found */
+ c = pgetc_macro();
+
+ if ((c != ' ') && (c != '\t')
+#ifdef CONFIG_ASH_ALIAS
+ && (c != PEOA)
+#endif
+ ) {
+ if (c == '#') {
+ while ((c = pgetc()) != '\n' && c != PEOF);
+ pungetc();
+ } else if (c == '\\') {
+ if (pgetc() != '\n') {
+ pungetc();
+ goto READTOKEN1;
+ }
+ startlinno = ++plinno;
+ if (doprompt)
+ setprompt(2);
+ } else {
+ const char *p
+ = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
+
+ if (c != PEOF) {
+ if (c == '\n') {
+ plinno++;
+ needprompt = doprompt;
+ }
+
+ p = strchr(xxreadtoken_chars, c);
+ if (p == NULL) {
+ READTOKEN1:
+ return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
+ }
+
+ if (p - xxreadtoken_chars >= xxreadtoken_singles) {
+ if (pgetc() == *p) { /* double occurrence? */
+ p += xxreadtoken_doubles + 1;
+ } else {
+ pungetc();
+ }
+ }
+ }
+
+ return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
+ }
+ }
+ }
+}
+
+
+#else
#define RETURN(token) return lasttoken = token
static int
@@ -9918,7 +10005,7 @@ breakloop:
return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
#undef RETURN
}
-
+#endif /* NEW_xxreadtoken */
/*
@@ -10909,10 +10996,6 @@ redirect(union node *redir, int flags)
}
-
-
-
-
/*
* Undo the effects of the last redirection.
*/
@@ -10962,7 +11045,6 @@ clearredir(int drop)
}
-
/*
* Copy a file descriptor to be >= to. Returns -1
* if the source file descriptor is closed, EMPTY if there are no unused
@@ -11073,7 +11155,6 @@ binop:
}
-
static void
shcmd(union node *cmd, FILE *fp)
{
@@ -11422,7 +11503,6 @@ trapcmd(int argc, char **argv)
}
-
/*
* Clear traps on a fork.
*/
@@ -11445,7 +11525,6 @@ clear_traps(void)
}
-
/*
* Set the signal handler for the specified signal. The routine figures
* out what it should be set to.
@@ -11546,7 +11625,6 @@ ignoresig(int signo)
}
-
/*
* Signal handler.
*/
@@ -11565,7 +11643,6 @@ onsig(int signo)
}
-
/*
* Called to execute a trap. Perhaps we should avoid entering new trap
* handlers while we are executing a trap handler.
@@ -11591,12 +11668,10 @@ dotrap(void)
}
-
/*
* Controls whether the shell is interactive or not.
*/
-
void
setinteractive(int on)
{
@@ -11691,7 +11766,6 @@ exitshell(void)
}
#endif
out:
- out1c('\n');
_exit(status);
/* NOTREACHED */
}
@@ -11780,7 +11854,6 @@ setvar(const char *name, const char *val, int flags)
}
-
/*
* Same as setvar except that the variable and value are passed in
* the first argument as name=value. Since the first argument will
@@ -11830,7 +11903,6 @@ setvareq(char *s, int flags)
}
-
/*
* Process a linked list of variable assignments.
*/
@@ -11866,7 +11938,6 @@ lookupvar(const char *name)
}
-
/*
* Search the environment of a builtin command.
*/
@@ -11884,7 +11955,6 @@ bltinlookup(const char *name)
}
-
/*
* Generate a list of variables satisfying the given conditions.
*/
@@ -11917,7 +11987,6 @@ listvars(int on, int off, char ***end)
}
-
/*
* POSIX requires that 'set' (but not export or readonly) output the
* variables in lexicographic order - by the locale's collating order (sigh).
@@ -12054,7 +12123,6 @@ localcmd(int argc, char **argv)
-
/*
* Called after a function returns.
* Interrupts must be off.
@@ -12568,7 +12636,7 @@ ulimitcmd(int argc, char **argv)
if (all || argptr[1])
error("too many arguments");
- if (strcmp(p, "unlimited") == 0)
+ if (strncmp(p, "unlimited\n", 9) == 0)
val = RLIM_INFINITY;
else {
val = (rlim_t) 0;