aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command.c10
-rw-r--r--src/hush.c38
-rw-r--r--src/variables.c57
3 files changed, 101 insertions, 4 deletions
diff --git a/src/command.c b/src/command.c
index 20b00b1..3d63121 100644
--- a/src/command.c
+++ b/src/command.c
@@ -119,7 +119,15 @@ pid_t execute_command(command *cmd) {
close(cmd->pipe[1]);
}
- execvp(cmd->command, cmd->args);
+ /*
+ * NOTE: discarding the const qualifier here is okay because either
+ * 1) exec fails, in which case the process is aborted immediately
+ * 2) exec succeeds, in which case the memory is released immediately
+ *
+ * In either case, the args won't be accessed again.
+ */
+ execvp(cmd->command, (char**)cmd->args);
+
perror("Could not run command");
exit(EXIT_FAILURE);
} else if (res < 0) {
diff --git a/src/hush.c b/src/hush.c
index 557ae1e..0d25244 100644
--- a/src/hush.c
+++ b/src/hush.c
@@ -14,6 +14,7 @@
#include "config.h"
#include "lexer.h"
#include "command.h"
+#include "variables.h"
FILE *open_input(int argc, char **argv) {
FILE *input_file = (argc > 1) ? fopen(argv[1], "r") : stdin;
@@ -34,10 +35,38 @@ static size_t get_command_len(char *cmdstr) {
return len;
}
+void variable_substitution(command *cmds) {
+ for (command *cmd = cmds; cmd; cmd = cmd->next) {
+ fprintf(stderr, "Before substitution\n");
+ print_commands(stderr, cmd);
+ for (size_t i=0; i < MAX_ARGUMENT_CNT + 1; i++) {
+ if (is_variable(cmd->args[i])) {
+ cmd->args[i] = get_variable(cmd->args[i]);
+ }
+ }
+
+ if (is_variable(cmd->outfile)) {
+ cmd->outfile = get_variable(cmd->outfile);
+ }
+
+ if (is_variable(cmd->infile)) {
+ cmd->infile = get_variable(cmd->infile);
+ }
+
+ fprintf(stderr, "After substitution\n");
+ print_commands(stderr, cmd);
+ }
+}
+
int main(int argc, char **argv) {
FILE *input_file = open_input(argc, argv);
char buffer[MAX_LINE_LEN];
+ if (!init_variable_store()) {
+ fprintf(stderr, "ERROR: Failed to initialize variable store\n");
+ exit(EXIT_FAILURE);
+ }
+
fprintf(stdout, "$ ");
while (fgets(buffer, MAX_LINE_LEN, input_file)) {
char *cmdstr = trim(buffer);
@@ -68,7 +97,9 @@ int main(int argc, char **argv) {
// print_parsed_command(stdout, parsed_cmd);
if (parsed_cmd->type == TKN_VARKEY) {
- /* handle variable creation */
+ if (!add_variable(parsed_cmd->text, parsed_cmd->next->text)) {
+ fprintf(stderr, "ERROR: Failed to create variable\n");
+ }
goto free_tokens;
}
@@ -79,6 +110,7 @@ int main(int argc, char **argv) {
goto free_tokens;
}
+ variable_substitution(cmds);
for (command *cmd = cmds; cmd; cmd = cmd->next) {
pid_t result = execute_command(cmd);
@@ -91,9 +123,7 @@ int main(int argc, char **argv) {
for (command *cmd = cmds; cmd; cmd = cmd->next) {
if (cmd->pid > 0) {
- fprintf(stderr, "Waiting for %d\n", cmd->pid);
waitpid(cmd->pid, NULL, 0);
- fprintf(stderr, "%d completed\n", cmd->pid);
}
}
@@ -107,4 +137,6 @@ int main(int argc, char **argv) {
draw_prompt:
fprintf(stdout, "$ ");
}
+
+ destroy_variable_store();
}
diff --git a/src/variables.c b/src/variables.c
new file mode 100644
index 0000000..c7cc4da
--- /dev/null
+++ b/src/variables.c
@@ -0,0 +1,57 @@
+/*
+ *
+ */
+
+#include "variables.h"
+#include "strmap.h"
+
+static strmap *map;
+
+bool init_variable_store(void) {
+ map = strmap_create(hash_key);
+ return map;
+}
+
+bool add_variable(const char *key, const char *val) {
+ if (strmap_put(map, key, val) != STRMAP_OK) {
+ return false;
+ }
+
+ return true;
+}
+
+const char *get_variable(const char *key) {
+ fprintf(stderr, "Key is: %s\n", key);
+
+ key += (key[0] == '$');
+ const char *val;
+ strmap_status stat = strmap_get(map, key, &val);
+ switch (stat) {
+ case STRMAP_OK:
+ break;
+ case STRMAP_NOTFOUND:
+ val = getenv(key);
+ break;
+ default:
+ val = NULL;
+ break;
+ }
+
+ val = (val) ? val : "";
+ fprintf(stderr, "Value is: %s\n", val);
+
+ return val;
+}
+
+bool promote_variable_to_env(const char *key) {
+ const char *val = get_variable(key);
+ if (!val) {
+ val = "";
+ }
+
+ return !setenv(key, val, 1);
+}
+
+void destroy_variable_store() {
+ strmap_destroy(map);
+}