aboutsummaryrefslogtreecommitdiff
path: root/smash
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-02-14 09:33:29 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2023-02-14 09:33:29 +0100
commitdffe48ee9dec21e3dbcb374f938d747da8d66f12 (patch)
treef4a71f3ade01e2ece4dae580081a9834672911d5 /smash
parentcf625ea48ac09b8b484f90e5971e2d8001aa76de (diff)
add set env variables
Diffstat (limited to 'smash')
-rw-r--r--smash/Makefile2
-rw-r--r--smash/env.c1
-rw-r--r--smash/exec.c9
-rw-r--r--smash/main.c9
-rw-r--r--smash/variable.c75
-rw-r--r--smash/variable.h8
6 files changed, 98 insertions, 6 deletions
diff --git a/smash/Makefile b/smash/Makefile
index 0f90909..569ee21 100644
--- a/smash/Makefile
+++ b/smash/Makefile
@@ -1,6 +1,6 @@
SRC=$(wildcard *.c)
OBJ=$(SRC:%.c=objects/%.o)
-CFLAGS=-static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -fno-builtin -g
+CFLAGS=-static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -fno-builtin -Wno-int-conversion -Wno-pointer-to-int-cast -g
default_target: smash
diff --git a/smash/env.c b/smash/env.c
index 69e5e68..e14dba1 100644
--- a/smash/env.c
+++ b/smash/env.c
@@ -54,6 +54,7 @@ char* new_line_and_replace_vars(const char *line, u64 n)
}
replaced = malloc(size + 1);
+ clear_buf(replaced, size + 1);
int line_pos = 0;
for (int i = 0; i < size && line[line_pos]; ++i) {
diff --git a/smash/exec.c b/smash/exec.c
index b37576a..779fccd 100644
--- a/smash/exec.c
+++ b/smash/exec.c
@@ -1,4 +1,7 @@
#include "exec.h"
+#include "parser.h"
+#include "builtin.h"
+#include "variable.h"
#include "../lib/sys/execve.h"
#include "../lib/sys/fork.h"
@@ -13,9 +16,6 @@
#include "../lib/malloc/malloc.h"
#include "../lib/list/list.h"
-#include "parser.h"
-#include "builtin.h"
-
void print_call(char **argv)
{
while (*argv) {
@@ -89,6 +89,9 @@ void exec(char *line)
}
if (exp->next)
dup2(pipefd[1][PIPE_IN], STDOUT_FD);
+ else if (get_end_fd() != STDOUT_FD)
+ dup2(get_end_fd(), STDOUT_FD);
+
close(pipefd[1][PIPE_OUT]);
close(pipefd[1][PIPE_IN]);
diff --git a/smash/main.c b/smash/main.c
index e36744d..cf5f47f 100644
--- a/smash/main.c
+++ b/smash/main.c
@@ -1,6 +1,7 @@
#include "exec.h"
#include "comment.h"
#include "env.h"
+#include "variable.h"
#include "../lib/sys/io.h"
#include "../lib/cstr/cstr.h"
@@ -19,6 +20,7 @@ int main(int argc, char *argv[])
int fd = STDIN_FD;
char linebuf[BUFSIZ];
char *line;
+ char *line_exec;
init_arg_env(argc, (const char**)argv);
@@ -43,12 +45,15 @@ int main(int argc, char *argv[])
remove_comment(linebuf);
line = new_line_and_replace_vars(linebuf, BUFSIZ);
- line_length = cstr_length(line);
+ line_exec = setup_variable_line_context(line);
+ line_length = cstr_length(line_exec);
if (line_length > 0) {
- exec(line);
+ exec(line_exec);
}
+ cleanup_variable_line_context();
+
free(line);
}
diff --git a/smash/variable.c b/smash/variable.c
new file mode 100644
index 0000000..d3855c6
--- /dev/null
+++ b/smash/variable.c
@@ -0,0 +1,75 @@
+#include "variable.h"
+#include "../lib/cstr/cstr.h"
+#include "../lib/sys/pipe.h"
+#include "../lib/sys/dup2.h"
+#include "../lib/io/io.h"
+#include "../lib/sys/types.h"
+#include "../lib/env/env.h"
+
+
+char current_write_variable[128] = { 0 };
+int fd[2];
+char readbuf[BUFSIZ];
+
+void cleanbuf(char *buf, int n) {
+ for (int i = 0; i < n; ++i) buf[i] = 0;
+}
+
+char *setup_variable_line_context(char *line)
+{
+ char* start = line;
+ fd[PIPE_IN] = STDOUT_FD;
+ cleanbuf(current_write_variable, 128);
+
+ if (line[0] != '[')
+ return line;
+
+ int i = 0;
+ ++line;
+
+ while (*line != ']') current_write_variable[i++] = *(line++);
+
+ if (*(++line) != '=') {
+ return start;
+ }
+
+ ++line;
+ current_write_variable[i] = 0;
+
+ pipe(fd);
+
+ return line;
+}
+
+
+void cleanup_variable_line_context()
+{
+ u64 size = 0;
+ u64 string_size = 0;
+
+ if (current_write_variable[0] == 0)
+ return;
+
+ cleanbuf(readbuf, BUFSIZ);
+
+ close(fd[PIPE_IN]);
+
+ while ((size = read(fd[PIPE_OUT], readbuf + string_size, BUFSIZ))) {
+ string_size += size;
+ }
+
+ readbuf[string_size] = 0;
+
+ if (readbuf[string_size - 1] == '\n')
+ readbuf[string_size - 1] = 0;
+
+ setenv(current_write_variable, readbuf);
+
+ close(fd[PIPE_OUT]);
+}
+
+
+int get_end_fd()
+{
+ return fd[PIPE_IN];
+}
diff --git a/smash/variable.h b/smash/variable.h
new file mode 100644
index 0000000..1c212f1
--- /dev/null
+++ b/smash/variable.h
@@ -0,0 +1,8 @@
+#ifndef VARIABLE_H
+#define VARIABLE_H
+
+char *setup_variable_line_context(char *line);
+void cleanup_variable_line_context();
+int get_end_fd();
+
+#endif