Might as well commit this to have the history. It's not linked in to the
authorRob Landley <rob@landley.net>
Tue, 5 Sep 2006 03:22:19 +0000 (03:22 -0000)
committerRob Landley <rob@landley.net>
Tue, 5 Sep 2006 03:22:19 +0000 (03:22 -0000)
applet list yet (and won't be until it can replace lash, I'm not having five
shells in menuconfig at once), but you can build it with scripts/individual
and mostly this is checked in so I can bloatcheck future versions against it
easily....

This is about as small as a shell can get and still be a shell.

shell/bbsh.c [new file with mode: 0644]

diff --git a/shell/bbsh.c b/shell/bbsh.c
new file mode 100644 (file)
index 0000000..f2d76cc
--- /dev/null
@@ -0,0 +1,73 @@
+/* vi: set ts=4 :
+ * 
+ * bbsh - busybox shell
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+// Handle embedded NUL bytes in the command line.
+
+#include <busybox.h>
+
+static int handle(char *command)
+{
+       int argc=0;
+       char *argv[10], *start = command;
+
+       // Parse command into argv[]
+       for (;;) {
+               char *end;
+
+               // Skip leading whitespace and detect EOL.
+               while(isspace(*start)) start++;
+               if(!*start || *start=='#') break;
+
+               // Grab next word.  (Add dequote and envvar logic here)
+               end=start;
+               while(*end && !isspace(*end)) end++;
+               argv[argc++]=xstrndup(start,end-start);
+               start=end;
+       }
+       argv[argc]=0;
+
+       if (!argc) return 0;
+       if (argc==2 && !strcmp(argv[0],"cd")) chdir(argv[1]);
+       else if(!strcmp(argv[0],"exit")) exit(argc>1 ? atoi(argv[1]) : 0); 
+       else {
+               int status;
+               pid_t pid=fork();
+               if(!pid) {
+                       run_applet_by_name(argv[0],argc,argv);
+                       execvp(argv[0],argv);
+                       printf("No %s",argv[0]);
+                       exit(1);
+               } else waitpid(pid, &status, 0);
+       }
+       while(argc) free(argv[--argc]);
+
+       return 0;
+}
+
+int bbsh_main(int argc, char *argv[])
+{
+       char *command=NULL;
+       FILE *f;
+
+       bb_getopt_ulflags(argc, argv, "c:", &command);
+
+       f = argv[optind] ? xfopen(argv[optind],"r") : NULL;
+       if (command) handle(command);
+       else {
+               unsigned cmdlen=0;
+               for (;;) {
+                       if(!f) putchar('$');
+                       if(1 > getline(&command,&cmdlen,f ? : stdin)) break;
+                       handle(command);
+               }
+               if (ENABLE_FEATURE_CLEAN_UP) free(command);
+       }
+               
+       return 1;
+}