aboutsummaryrefslogtreecommitdiff
path: root/toys/toysh.c
diff options
context:
space:
mode:
authorlandley <landley@driftwood>2006-10-05 16:18:03 -0400
committerlandley <landley@driftwood>2006-10-05 16:18:03 -0400
commit4f344e356d2c36c4b1df46917eaef25f82ca79a9 (patch)
treecae824af861d5665b1acf1e4b07de86c256c2d0b /toys/toysh.c
parentc56215062c961402515daeef8330ed75cd94af29 (diff)
downloadtoybox-4f344e356d2c36c4b1df46917eaef25f82ca79a9.tar.gz
Infrastructure, first drop of toy shell, and a bit of work on df.
Diffstat (limited to 'toys/toysh.c')
-rw-r--r--toys/toysh.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/toys/toysh.c b/toys/toysh.c
new file mode 100644
index 00000000..77db82db
--- /dev/null
+++ b/toys/toysh.c
@@ -0,0 +1,92 @@
+/* vi: set sw=4 ts=4:
+ *
+ * toysh - toybox shell
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ *
+ * The spec for this is at:
+ * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
+ *
+ * Although things like the bash man page are good to read too.
+ */
+
+// Handle embedded NUL bytes in the command line.
+
+#include "toys.h"
+
+static int handle(char *command)
+{
+ int argc = 0, status;
+ char *argv[10], *start = command;
+ pid_t pid;
+ struct toy_list *tl;
+
+ // 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;
+
+ tl = toy_find(argv[0]);
+ // This is a bit awkward, next design cycle should clean it up.
+ // Should vfork(), move to tryspawn()?
+ pid = 0;
+ if (tl && (tl->flags & TOYFLAG_NOFORK))
+ status = tl->toy_main();
+ else {
+ pid=fork();
+ if(!pid) {
+ toy_exec(argv);
+ xexec(argv);
+ } else waitpid(pid, &status, 0);
+ }
+ while(argc) free(argv[--argc]);
+
+ return 0;
+}
+
+int cd_main(void)
+{
+ char *dest = toys.argc>1 ? toys.argv[1] : getenv("HOME");
+ if (chdir(dest)) error_exit("chdir %s",dest);
+ return 0;
+}
+
+int exit_main(void)
+{
+ exit(toys.argc>1 ? atoi(toys.argv[1]) : 0);
+}
+
+int toysh_main(void)
+{
+ char *command=NULL;
+ FILE *f;
+
+ // TODO get_optflags(argv, "c:", &command);
+
+ f = toys.argv[1] ? xfopen(toys.argv[1], "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 (CFG_TOYS_FREE) free(command);
+ }
+
+ return 1;
+}