Add in a shell tagline (per lash/hush behavior) to make it easier
to know which shell is in use. Add in 'help' to list available
builtins, and fixup msh so it can do STANDALONE_SHELL.
-Erik
diff --git a/ash.c b/ash.c
index 99460d3..4250f50 100644
--- a/ash.c
+++ b/ash.c
@@ -1603,6 +1603,7 @@
static int exportcmd (int, char **);
static int histcmd (int, char **);
static int hashcmd (int, char **);
+static int helpcmd (int, char **);
static int jobscmd (int, char **);
static int localcmd (int, char **);
#ifndef BB_PWD
@@ -1704,6 +1705,7 @@
{ BUILTIN_REGULAR "getopts", getoptscmd },
#endif
{ BUILTIN_NOSPEC "hash", hashcmd },
+ { BUILTIN_NOSPEC "help", helpcmd },
{ BUILTIN_REGULAR "jobs", jobscmd },
#ifdef JOBS
{ BUILTIN_REGULAR "kill", killcmd },
@@ -3274,6 +3276,7 @@
setinteractive(int on)
{
static int is_interactive;
+ static int do_banner=0;
if (on == is_interactive)
return;
@@ -3282,6 +3285,12 @@
setsignal(SIGTERM);
chkmail(1);
is_interactive = on;
+ if (do_banner==0 && is_interactive) {
+ /* Looks like they want an interactive shell */
+ printf( "\n\n" BB_BANNER " Built-in shell (ash)\n");
+ printf( "Enter 'help' for a list of built-in commands.\n\n");
+ do_banner=1;
+ }
}
static void
@@ -3802,6 +3811,51 @@
+/*** List the available builtins ***/
+
+
+static int helpcmd(int argc, char** argv)
+{
+ int col, i;
+ const struct builtincmd *x;
+
+ printf("\nBuilt-in commands:\n");
+ printf("-------------------\n");
+ for (col=0, i=0, x = builtincmds; i < NUMBUILTINS; x++, i++) {
+ if (!x->name || ! (x->name+1))
+ continue;
+ col += printf("%s%s", ((col == 0) ? "\t" : " "),
+ (x->name+1));
+ if (col > 60) {
+ printf("\n");
+ col = 0;
+ }
+ }
+#ifdef BB_FEATURE_SH_STANDALONE_SHELL
+ {
+ const struct BB_applet *applet;
+ extern const struct BB_applet applets[];
+ extern const size_t NUM_APPLETS;
+
+ for (i=0, applet = applets; i < NUM_APPLETS; applet++, i++) {
+ if (!applet->name)
+ continue;
+
+ col += printf("%s%s", ((col == 0) ? "\t" : " "),
+ applet->name);
+ if (col > 60) {
+ printf("\n");
+ col = 0;
+ }
+ }
+ }
+#endif
+ printf("\n\n");
+ return EXIT_SUCCESS;
+}
+
+
+
/*
* Resolve a command name. If you change this routine, you may have to
* change the shellexec routine as well.
@@ -7755,6 +7809,11 @@
EXECCMD = find_builtin("exec");
EVALCMD = find_builtin("eval");
+#ifndef BB_FEATURE_SH_FANCY_PROMPT
+ unsetenv("PS1");
+ unsetenv("PS2");
+#endif
+
#if PROFILE
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
#endif
@@ -13088,7 +13147,7 @@
/*
* Copyright (c) 1999 Herbert Xu <herbert@debian.org>
* This file contains code for the times builtin.
- * $Id: ash.c,v 1.6 2001/07/06 04:26:23 andersen Exp $
+ * $Id: ash.c,v 1.7 2001/07/07 00:05:55 andersen Exp $
*/
static int timescmd (int argc, char **argv)
{
diff --git a/msh.c b/msh.c
index 66c3d54..e85d6ff 100644
--- a/msh.c
+++ b/msh.c
@@ -497,6 +497,7 @@
static struct op *findcase (struct op *t, char *w );
static void brkset(struct brkcon *bc );
static int dolabel(void);
+static int dohelp(void);
static int dochdir(struct op *t );
static int doshift(struct op *t );
static int dologin(struct op *t );
@@ -592,30 +593,31 @@
};
-struct builtin {
- char *command;
- int (*fn)();
+struct builtincmd {
+ const char *name;
+ int (*builtinfunc)();
};
-static struct builtin builtin[] = {
+static const struct builtincmd builtincmds[] = {
+ {".", dodot},
{":", dolabel},
- {"cd", dochdir},
- {"shift", doshift},
- {"exec", doexec},
- {"wait", dowait},
- {"read", doread},
- {"eval", doeval},
- {"trap", dotrap},
{"break", dobreak},
+ {"cd", dochdir},
{"continue",docontinue},
+ {"eval", doeval},
+ {"exec", doexec},
{"exit", doexit},
{"export", doexport},
- {"readonly",doreadonly},
- {"set", doset},
- {".", dodot},
- {"umask", doumask},
+ {"help", dohelp},
{"login", dologin},
{"newgrp", dologin},
+ {"read", doread},
+ {"readonly",doreadonly},
+ {"set", doset},
+ {"shift", doshift},
{"times", dotimes},
+ {"trap", dotrap},
+ {"umask", doumask},
+ {"wait", dowait},
{0,0}
};
@@ -731,14 +733,18 @@
setval(ifs, " \t\n");
prompt = lookup("PS1");
+#ifdef BB_FEATURE_SH_FANCY_PROMPT
if (prompt->value == null)
+#endif
setval(prompt, "$ ");
if (geteuid() == 0) {
setval(prompt, "# ");
prompt->status &= ~EXPORT;
}
cprompt = lookup("PS2");
+#ifdef BB_FEATURE_SH_FANCY_PROMPT
if (cprompt->value == null)
+#endif
setval(cprompt, "> ");
iof = filechar;
@@ -794,8 +800,11 @@
setdash();
if (e.iop < iostack) {
PUSHIO(afile, 0, iof);
- if (isatty(0) && isatty(1) && !cflag)
+ if (isatty(0) && isatty(1) && !cflag) {
interactive++;
+ printf( "\n\n" BB_BANNER " Built-in shell (msh)\n");
+ printf( "Enter 'help' for a list of built-in commands.\n\n");
+ }
}
signal(SIGQUIT, qflag);
if (name && name[0] == '-') {
@@ -2314,14 +2323,14 @@
switch(t->type) {
case TPAREN:
case TCOM:
- {
- int child;
- rv = forkexec(t, pin, pout, act, wp, &child);
- if (child) {
- exstat = rv;
- leave();
+ {
+ int child;
+ rv = forkexec(t, pin, pout, act, wp, &child);
+ if (child) {
+ exstat = rv;
+ leave();
+ }
}
- }
break;
case TPIPE:
@@ -2828,6 +2837,21 @@
register char *sp, *tp;
int eacces = 0, asis = 0;
+#ifdef BB_FEATURE_SH_STANDALONE_SHELL
+ char *name = c;
+#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
+ name = get_last_path_component(name);
+#endif
+ optind = 1;
+ if (find_applet_by_name(name)) {
+ /* We have to exec here since we vforked. Running
+ * run_applet_by_name() won't work and bad things
+ * will happen. */
+ execve("/proc/self/exe", v, envp);
+ execve("busybox", v, envp);
+ }
+#endif
+
sp = any('/', c)? "": path->value;
asis = *sp == '\0';
while (asis || *sp != '\0') {
@@ -2842,6 +2866,8 @@
*tp++ = '/';
for (i = 0; (*tp++ = c[i++]) != '\0';)
;
+
+ fprintf(stderr, "calling exec\n");
execve(e.linep, v, envp);
switch (errno) {
case ENOEXEC:
@@ -2917,6 +2943,49 @@
* built-in commands: doX
*/
+static int dohelp()
+{
+ int col;
+ const struct builtincmd *x;
+
+ printf("\nBuilt-in commands:\n");
+ printf("-------------------\n");
+
+ for (col=0, x = builtincmds; x->builtinfunc != NULL; x++) {
+ if (!x->name)
+ continue;
+ col += printf("%s%s", ((col == 0) ? "\t" : " "), x->name);
+ if (col > 60) {
+ printf("\n");
+ col = 0;
+ }
+ }
+#ifdef BB_FEATURE_SH_STANDALONE_SHELL
+ {
+ int i;
+ const struct BB_applet *applet;
+ extern const struct BB_applet applets[];
+ extern const size_t NUM_APPLETS;
+
+ for (i=0, applet = applets; i < NUM_APPLETS; applet++, i++) {
+ if (!applet->name)
+ continue;
+
+ col += printf("%s%s", ((col == 0) ? "\t" : " "),
+ applet->name);
+ if (col > 60) {
+ printf("\n");
+ col = 0;
+ }
+ }
+ }
+#endif
+ printf("\n\n");
+ return EXIT_SUCCESS;
+}
+
+
+
static int
dolabel()
{
@@ -3341,7 +3410,6 @@
/*
* Copyright (c) 1999 Herbert Xu <herbert@debian.org>
* This file contains code for the times builtin.
- * $Id: msh.c,v 1.1 2001/06/29 04:57:14 andersen Exp $
*/
static int dotimes ()
{
@@ -3362,14 +3430,14 @@
}
-static int (*inbuilt(s))()
-register char *s;
+static int (*inbuilt(char *s))()
{
- register struct builtin *bp;
+ const struct builtincmd *bp;
- for (bp = builtin; bp->command != NULL; bp++)
- if (strcmp(bp->command, s) == 0)
- return(bp->fn);
+ for (bp = builtincmds; bp->name != NULL; bp++)
+ if (strcmp(bp->name, s) == 0)
+ return(bp->builtinfunc);
+
return((int(*)())NULL);
}
diff --git a/sh.c b/sh.c
index e763436..15a3070 100644
--- a/sh.c
+++ b/sh.c
@@ -20,6 +20,15 @@
#include "busybox.h"
+/* This is to make testing things a bit simpler (to avoid
+ * a full recompile) till we get the new build system in place */
+#if 0
+#undef BB_FEATURE_LASH
+#undef BB_FEATURE_HUSH
+#undef BB_FEATURE_MSH
+#define BB_FEATURE_ASH
+#endif
+
#if defined BB_FEATURE_ASH
#include "ash.c"
#elif defined BB_FEATURE_MSH
diff --git a/shell/ash.c b/shell/ash.c
index 99460d3..4250f50 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1603,6 +1603,7 @@
static int exportcmd (int, char **);
static int histcmd (int, char **);
static int hashcmd (int, char **);
+static int helpcmd (int, char **);
static int jobscmd (int, char **);
static int localcmd (int, char **);
#ifndef BB_PWD
@@ -1704,6 +1705,7 @@
{ BUILTIN_REGULAR "getopts", getoptscmd },
#endif
{ BUILTIN_NOSPEC "hash", hashcmd },
+ { BUILTIN_NOSPEC "help", helpcmd },
{ BUILTIN_REGULAR "jobs", jobscmd },
#ifdef JOBS
{ BUILTIN_REGULAR "kill", killcmd },
@@ -3274,6 +3276,7 @@
setinteractive(int on)
{
static int is_interactive;
+ static int do_banner=0;
if (on == is_interactive)
return;
@@ -3282,6 +3285,12 @@
setsignal(SIGTERM);
chkmail(1);
is_interactive = on;
+ if (do_banner==0 && is_interactive) {
+ /* Looks like they want an interactive shell */
+ printf( "\n\n" BB_BANNER " Built-in shell (ash)\n");
+ printf( "Enter 'help' for a list of built-in commands.\n\n");
+ do_banner=1;
+ }
}
static void
@@ -3802,6 +3811,51 @@
+/*** List the available builtins ***/
+
+
+static int helpcmd(int argc, char** argv)
+{
+ int col, i;
+ const struct builtincmd *x;
+
+ printf("\nBuilt-in commands:\n");
+ printf("-------------------\n");
+ for (col=0, i=0, x = builtincmds; i < NUMBUILTINS; x++, i++) {
+ if (!x->name || ! (x->name+1))
+ continue;
+ col += printf("%s%s", ((col == 0) ? "\t" : " "),
+ (x->name+1));
+ if (col > 60) {
+ printf("\n");
+ col = 0;
+ }
+ }
+#ifdef BB_FEATURE_SH_STANDALONE_SHELL
+ {
+ const struct BB_applet *applet;
+ extern const struct BB_applet applets[];
+ extern const size_t NUM_APPLETS;
+
+ for (i=0, applet = applets; i < NUM_APPLETS; applet++, i++) {
+ if (!applet->name)
+ continue;
+
+ col += printf("%s%s", ((col == 0) ? "\t" : " "),
+ applet->name);
+ if (col > 60) {
+ printf("\n");
+ col = 0;
+ }
+ }
+ }
+#endif
+ printf("\n\n");
+ return EXIT_SUCCESS;
+}
+
+
+
/*
* Resolve a command name. If you change this routine, you may have to
* change the shellexec routine as well.
@@ -7755,6 +7809,11 @@
EXECCMD = find_builtin("exec");
EVALCMD = find_builtin("eval");
+#ifndef BB_FEATURE_SH_FANCY_PROMPT
+ unsetenv("PS1");
+ unsetenv("PS2");
+#endif
+
#if PROFILE
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
#endif
@@ -13088,7 +13147,7 @@
/*
* Copyright (c) 1999 Herbert Xu <herbert@debian.org>
* This file contains code for the times builtin.
- * $Id: ash.c,v 1.6 2001/07/06 04:26:23 andersen Exp $
+ * $Id: ash.c,v 1.7 2001/07/07 00:05:55 andersen Exp $
*/
static int timescmd (int argc, char **argv)
{
diff --git a/shell/msh.c b/shell/msh.c
index 66c3d54..e85d6ff 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -497,6 +497,7 @@
static struct op *findcase (struct op *t, char *w );
static void brkset(struct brkcon *bc );
static int dolabel(void);
+static int dohelp(void);
static int dochdir(struct op *t );
static int doshift(struct op *t );
static int dologin(struct op *t );
@@ -592,30 +593,31 @@
};
-struct builtin {
- char *command;
- int (*fn)();
+struct builtincmd {
+ const char *name;
+ int (*builtinfunc)();
};
-static struct builtin builtin[] = {
+static const struct builtincmd builtincmds[] = {
+ {".", dodot},
{":", dolabel},
- {"cd", dochdir},
- {"shift", doshift},
- {"exec", doexec},
- {"wait", dowait},
- {"read", doread},
- {"eval", doeval},
- {"trap", dotrap},
{"break", dobreak},
+ {"cd", dochdir},
{"continue",docontinue},
+ {"eval", doeval},
+ {"exec", doexec},
{"exit", doexit},
{"export", doexport},
- {"readonly",doreadonly},
- {"set", doset},
- {".", dodot},
- {"umask", doumask},
+ {"help", dohelp},
{"login", dologin},
{"newgrp", dologin},
+ {"read", doread},
+ {"readonly",doreadonly},
+ {"set", doset},
+ {"shift", doshift},
{"times", dotimes},
+ {"trap", dotrap},
+ {"umask", doumask},
+ {"wait", dowait},
{0,0}
};
@@ -731,14 +733,18 @@
setval(ifs, " \t\n");
prompt = lookup("PS1");
+#ifdef BB_FEATURE_SH_FANCY_PROMPT
if (prompt->value == null)
+#endif
setval(prompt, "$ ");
if (geteuid() == 0) {
setval(prompt, "# ");
prompt->status &= ~EXPORT;
}
cprompt = lookup("PS2");
+#ifdef BB_FEATURE_SH_FANCY_PROMPT
if (cprompt->value == null)
+#endif
setval(cprompt, "> ");
iof = filechar;
@@ -794,8 +800,11 @@
setdash();
if (e.iop < iostack) {
PUSHIO(afile, 0, iof);
- if (isatty(0) && isatty(1) && !cflag)
+ if (isatty(0) && isatty(1) && !cflag) {
interactive++;
+ printf( "\n\n" BB_BANNER " Built-in shell (msh)\n");
+ printf( "Enter 'help' for a list of built-in commands.\n\n");
+ }
}
signal(SIGQUIT, qflag);
if (name && name[0] == '-') {
@@ -2314,14 +2323,14 @@
switch(t->type) {
case TPAREN:
case TCOM:
- {
- int child;
- rv = forkexec(t, pin, pout, act, wp, &child);
- if (child) {
- exstat = rv;
- leave();
+ {
+ int child;
+ rv = forkexec(t, pin, pout, act, wp, &child);
+ if (child) {
+ exstat = rv;
+ leave();
+ }
}
- }
break;
case TPIPE:
@@ -2828,6 +2837,21 @@
register char *sp, *tp;
int eacces = 0, asis = 0;
+#ifdef BB_FEATURE_SH_STANDALONE_SHELL
+ char *name = c;
+#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
+ name = get_last_path_component(name);
+#endif
+ optind = 1;
+ if (find_applet_by_name(name)) {
+ /* We have to exec here since we vforked. Running
+ * run_applet_by_name() won't work and bad things
+ * will happen. */
+ execve("/proc/self/exe", v, envp);
+ execve("busybox", v, envp);
+ }
+#endif
+
sp = any('/', c)? "": path->value;
asis = *sp == '\0';
while (asis || *sp != '\0') {
@@ -2842,6 +2866,8 @@
*tp++ = '/';
for (i = 0; (*tp++ = c[i++]) != '\0';)
;
+
+ fprintf(stderr, "calling exec\n");
execve(e.linep, v, envp);
switch (errno) {
case ENOEXEC:
@@ -2917,6 +2943,49 @@
* built-in commands: doX
*/
+static int dohelp()
+{
+ int col;
+ const struct builtincmd *x;
+
+ printf("\nBuilt-in commands:\n");
+ printf("-------------------\n");
+
+ for (col=0, x = builtincmds; x->builtinfunc != NULL; x++) {
+ if (!x->name)
+ continue;
+ col += printf("%s%s", ((col == 0) ? "\t" : " "), x->name);
+ if (col > 60) {
+ printf("\n");
+ col = 0;
+ }
+ }
+#ifdef BB_FEATURE_SH_STANDALONE_SHELL
+ {
+ int i;
+ const struct BB_applet *applet;
+ extern const struct BB_applet applets[];
+ extern const size_t NUM_APPLETS;
+
+ for (i=0, applet = applets; i < NUM_APPLETS; applet++, i++) {
+ if (!applet->name)
+ continue;
+
+ col += printf("%s%s", ((col == 0) ? "\t" : " "),
+ applet->name);
+ if (col > 60) {
+ printf("\n");
+ col = 0;
+ }
+ }
+ }
+#endif
+ printf("\n\n");
+ return EXIT_SUCCESS;
+}
+
+
+
static int
dolabel()
{
@@ -3341,7 +3410,6 @@
/*
* Copyright (c) 1999 Herbert Xu <herbert@debian.org>
* This file contains code for the times builtin.
- * $Id: msh.c,v 1.1 2001/06/29 04:57:14 andersen Exp $
*/
static int dotimes ()
{
@@ -3362,14 +3430,14 @@
}
-static int (*inbuilt(s))()
-register char *s;
+static int (*inbuilt(char *s))()
{
- register struct builtin *bp;
+ const struct builtincmd *bp;
- for (bp = builtin; bp->command != NULL; bp++)
- if (strcmp(bp->command, s) == 0)
- return(bp->fn);
+ for (bp = builtincmds; bp->name != NULL; bp++)
+ if (strcmp(bp->name, s) == 0)
+ return(bp->builtinfunc);
+
return((int(*)())NULL);
}