summaryrefslogtreecommitdiff
path: root/usr.bin/osh/osh.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/osh/osh.c')
-rw-r--r--usr.bin/osh/osh.c131
1 files changed, 98 insertions, 33 deletions
diff --git a/usr.bin/osh/osh.c b/usr.bin/osh/osh.c
index efb159e..d458173 100644
--- a/usr.bin/osh/osh.c
+++ b/usr.bin/osh/osh.c
@@ -67,11 +67,30 @@ static int running;
static int bell_fd;
static bool bs_bell = true; /* Beep on backspace */
+static void cmd_help(int argc, char *argv[]);
+static void cmd_echo(int argc, char *argv[]);
+static void cmd_exit(int argc, char *argv[]);
+static void cmd_reboot(int argc, char *argv[]);
+static void cmd_shutdown(int argc, char *argv[]);
+static void cmd_bell(int argc, char *argv[]);
+static void cmd_clear(int argc, char *argv[]);
+
struct builtin_cmd {
const char *name;
void (*func)(int argc, char *argv[]);
};
+static struct builtin_cmd cmds[] = {
+ {"help",cmd_help},
+ {"echo",cmd_echo},
+ {"exit",cmd_exit},
+ {"reboot",cmd_reboot},
+ {"shutdown", cmd_shutdown},
+ {"bell", cmd_bell},
+ {"clear", cmd_clear},
+ {NULL, NULL}
+};
+
static void
cmd_help(int argc, char *argv[])
{
@@ -223,11 +242,11 @@ builtin_run(struct builtin_cmd *cmd, int argc, char *argv[])
}
static int
-cmd_run(const char *input, int argc, char *argv[])
+cmd_run(const char *input, int argc, char *argv[], bool wait)
{
- char bin_path[256];
+ char bin_path[512];
char *envp[1] = { NULL };
- int error;
+ int error, spawn_flags = 0;
snprintf(bin_path, sizeof(bin_path), "/usr/bin/%s", input);
@@ -236,31 +255,90 @@ cmd_run(const char *input, int argc, char *argv[])
return -1;
}
- if ((error = spawn(bin_path, argv, envp, SPAWN_WAIT)) < 0) {
+ /* Should we wait or daemonize? */
+ if (wait) {
+ spawn_flags |= SPAWN_WAIT;
+ }
+
+ if ((error = spawn(bin_path, argv, envp, spawn_flags)) < 0) {
return error;
}
return 0;
}
-struct builtin_cmd cmds[] = {
- {"help",cmd_help},
- {"echo",cmd_echo},
- {"exit",cmd_exit},
- {"reboot",cmd_reboot},
- {"shutdown", cmd_shutdown},
- {"bell", cmd_bell},
- {"clear", cmd_clear},
- {NULL, NULL}
-};
+/*
+ * Match a command with a builtin or binary
+ *
+ * @input: Command input
+ * @argc: Argument count
+ * @argv: Argument vector
+ * @wait: If false, program will be daemonized
+ */
+static void
+command_match(const char *input, int argc, char *argv[], bool wait)
+{
+ int found = 0;
+ int i;
+
+ for (i = 0; cmds[i].name != NULL; i++) {
+ if (strcmp(input, cmds[i].name) == 0) {
+ builtin_run(&cmds[i], argc, argv);
+ found = 1;
+ break;
+ }
+ }
+
+ if (found == 0) {
+ if (cmd_run(input, argc, argv, wait) < 0) {
+ puts("Unrecognized command");
+ }
+ }
+}
+
+static int
+open_script(const char *pathname)
+{
+ int fd, argc, buf_i = 0;
+ char c, *input, *argv[16];
+ char buf[256];
+
+ fd = open(pathname, O_RDONLY);
+ if (fd < 0) {
+ printf("osh: failed to open %s\n", pathname);
+ return fd;
+ }
+
+ while (read(fd, &c, 1) > 0) {
+ if (buf_i >= sizeof(buf) - 1) {
+ buf_i = 0;
+ }
+
+ if (c == '\n') {
+ buf[buf_i] = '\0';
+ argc = parse_args(buf, argv, sizeof(argv));
+ command_match(buf, argc, argv, true);
+ buf_i = 0;
+ continue;
+ }
+ buf[buf_i++] = c;
+ }
+
+ return 0;
+}
int
-main(void)
+main(int argc, char **argv)
{
- int found, argc;
- char *input, *argv[16];
+ int found, prog_argc;
+ int stdout_fd;
+ char *input, *prog_argv[16], *p;
char c;
+ if (argc > 1) {
+ return open_script(argv[1]);
+ }
+
i = 0;
running = 1;
found = 0;
@@ -275,25 +353,12 @@ main(void)
continue;
}
- argc = parse_args(input, argv, sizeof(argv));
- if (argc == 0) {
+ prog_argc = parse_args(input, prog_argv, sizeof(prog_argv));
+ if (prog_argc == 0) {
continue;
}
- for (i = 0; cmds[i].name != NULL; i++) {
- if (strcmp(input, cmds[i].name) == 0) {
- builtin_run(&cmds[i], argc, argv);
- found = 1;
- break;
- }
- }
-
- if (found == 0) {
- if (cmd_run(input, argc, argv) < 0) {
- puts("Unrecognized command");
- }
- }
-
+ command_match(input, prog_argc, prog_argv, true);
found = 0;
buf[0] = '\0';
}