* zcat now works (wasn't working since option parsing was broken)
* Renamed "mnc" to the more correct "nc".
* Makefile intelligence updates
+ * BusyBox sh (lash) internals now behave wrt pipes and redirects.
+ * BusyBox sh (lash) now supports being used as a standalone shell. When
+ BB_FEATURE_STANDALONE_SHELL is defined, all the busybox commands may
+ be invoked as shell internals.
* More doc updates
void *__libc_stack_end;
#endif
-static const struct Applet applets[] = {
+const struct BB_applet applets[] = {
#ifdef BB_BASENAME
{"basename", basename_main, _BB_DIR_USR_BIN},
{
char *s;
char *name;
- const struct Applet *a = applets;
+ const struct BB_applet *a = applets;
for (s = name = argv[0]; *s != '\0';) {
if (*s++ == '/')
argv++;
if (been_there_done_that == 1 || argc < 1) {
- const struct Applet *a = applets;
+ const struct BB_applet *a = applets;
fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
BB_VER, BB_BT);
void *__libc_stack_end;
#endif
-static const struct Applet applets[] = {
+const struct BB_applet applets[] = {
#ifdef BB_BASENAME
{"basename", basename_main, _BB_DIR_USR_BIN},
{
char *s;
char *name;
- const struct Applet *a = applets;
+ const struct BB_applet *a = applets;
for (s = name = argv[0]; *s != '\0';) {
if (*s++ == '/')
argv++;
if (been_there_done_that == 1 || argc < 1) {
- const struct Applet *a = applets;
+ const struct BB_applet *a = applets;
fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
BB_VER, BB_BT);
// Enable command line editing in the shell
//#define BB_FEATURE_SH_COMMAND_EDITING
//
+//Allow the shell to invoke all the compiled in BusyBox commands as if they
+//were shell builtins. Nice for staticly linking an emergency rescue shell
+//amoung other thing.
+#ifdef BB_FEATURE_STANDALONE_SHELL
+//
// Enable tab completion in the shell (not yet
// working very well -- so don't turn this on)
//#define BB_FEATURE_SH_TAB_COMPLETION
_BB_DIR_USR_SBIN
};
-struct Applet {
+struct BB_applet {
const char* name;
int (*main)(int argc, char** argv);
enum Location location;
};
+/* From busybox.c */
+extern const struct BB_applet applets[];
extern int basename_main(int argc, char **argv);
extern int busybox_main(int argc, char** argv);
return 0;
}
+
static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
{
struct job *job;
int nextin, nextout;
int pipefds[2]; /* pipefd[0] is for reading */
struct builtInCommand *x;
+#ifdef BB_FEATURE_STANDALONE_SHELL
+ const struct BB_applet *a = applets;
+#endif
- /* handle built-ins here -- we don't fork() so we can't background
- these very easily */
- for (x = bltins; x->cmd; x++) {
- if (!strcmp(newJob.progs[0].argv[0], x->cmd)) {
- return (x->function(&newJob, jobList));
- }
- }
nextin = 0, nextout = 1;
for (i = 0; i < newJob.numProgs; i++) {
/* explicit redirections override pipes */
setupRedirections(newJob.progs + i);
+ /* Match any built-ins here */
+ for (x = bltins; x->cmd; x++) {
+ if (!strcmp(newJob.progs[i].argv[0], x->cmd)) {
+ exit (x->function(&newJob, jobList));
+ }
+ }
+#ifdef BB_FEATURE_STANDALONE_SHELL
+ /* Handle busybox internals here */
+ while (a->name != 0) {
+ if (strcmp(newJob.progs[i].argv[0], a->name) == 0) {
+ int argc;
+ char** argv=newJob.progs[i].argv;
+ for(argc=0;*argv!=NULL, argv++, argc++);
+ exit((*(a->main)) (argc, newJob.progs[i].argv));
+ }
+ a++;
+ }
+#endif
+
execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
strerror(errno));
return 0;
}
+
static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
{
struct job *job;
int nextin, nextout;
int pipefds[2]; /* pipefd[0] is for reading */
struct builtInCommand *x;
+#ifdef BB_FEATURE_STANDALONE_SHELL
+ const struct BB_applet *a = applets;
+#endif
- /* handle built-ins here -- we don't fork() so we can't background
- these very easily */
- for (x = bltins; x->cmd; x++) {
- if (!strcmp(newJob.progs[0].argv[0], x->cmd)) {
- return (x->function(&newJob, jobList));
- }
- }
nextin = 0, nextout = 1;
for (i = 0; i < newJob.numProgs; i++) {
/* explicit redirections override pipes */
setupRedirections(newJob.progs + i);
+ /* Match any built-ins here */
+ for (x = bltins; x->cmd; x++) {
+ if (!strcmp(newJob.progs[i].argv[0], x->cmd)) {
+ exit (x->function(&newJob, jobList));
+ }
+ }
+#ifdef BB_FEATURE_STANDALONE_SHELL
+ /* Handle busybox internals here */
+ while (a->name != 0) {
+ if (strcmp(newJob.progs[i].argv[0], a->name) == 0) {
+ int argc;
+ char** argv=newJob.progs[i].argv;
+ for(argc=0;*argv!=NULL, argv++, argc++);
+ exit((*(a->main)) (argc, newJob.progs[i].argv));
+ }
+ a++;
+ }
+#endif
+
execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
strerror(errno));
return 0;
}
+
static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
{
struct job *job;
int nextin, nextout;
int pipefds[2]; /* pipefd[0] is for reading */
struct builtInCommand *x;
+#ifdef BB_FEATURE_STANDALONE_SHELL
+ const struct BB_applet *a = applets;
+#endif
- /* handle built-ins here -- we don't fork() so we can't background
- these very easily */
- for (x = bltins; x->cmd; x++) {
- if (!strcmp(newJob.progs[0].argv[0], x->cmd)) {
- return (x->function(&newJob, jobList));
- }
- }
nextin = 0, nextout = 1;
for (i = 0; i < newJob.numProgs; i++) {
/* explicit redirections override pipes */
setupRedirections(newJob.progs + i);
+ /* Match any built-ins here */
+ for (x = bltins; x->cmd; x++) {
+ if (!strcmp(newJob.progs[i].argv[0], x->cmd)) {
+ exit (x->function(&newJob, jobList));
+ }
+ }
+#ifdef BB_FEATURE_STANDALONE_SHELL
+ /* Handle busybox internals here */
+ while (a->name != 0) {
+ if (strcmp(newJob.progs[i].argv[0], a->name) == 0) {
+ int argc;
+ char** argv=newJob.progs[i].argv;
+ for(argc=0;*argv!=NULL, argv++, argc++);
+ exit((*(a->main)) (argc, newJob.progs[i].argv));
+ }
+ a++;
+ }
+#endif
+
execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
strerror(errno));