aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sys/close.h11
-rw-r--r--lib/sys/dup2.h11
-rw-r--r--lib/sys/exit.h11
-rw-r--r--lib/sys/fork.h10
-rw-r--r--lib/sys/io.h11
-rw-r--r--lib/sys/pipe.h14
-rw-r--r--lib/sys/wait4.h12
-rw-r--r--lib/sys/write.h2
-rw-r--r--smash/Makefile2
-rw-r--r--smash/parser.c81
-rw-r--r--smash/parser.h7
-rwxr-xr-xsmash/testbin0 -> 26656 bytes
12 files changed, 154 insertions, 18 deletions
diff --git a/lib/sys/close.h b/lib/sys/close.h
new file mode 100644
index 0000000..2aa3a71
--- /dev/null
+++ b/lib/sys/close.h
@@ -0,0 +1,11 @@
+#ifndef CLOSE_H
+#define CLOSE_H
+
+#include "syscalls.h"
+
+int close(unsigned int fd)
+{
+ syscall(CLOSE, fd);
+}
+
+#endif
diff --git a/lib/sys/dup2.h b/lib/sys/dup2.h
new file mode 100644
index 0000000..7726efb
--- /dev/null
+++ b/lib/sys/dup2.h
@@ -0,0 +1,11 @@
+#ifndef DUP2_H
+#define DUP2_H
+
+#include "syscalls.h"
+
+int dup2(unsigned int oldfd, unsigned int newfd)
+{
+ return syscall(DUP2, oldfd, newfd);
+}
+
+#endif
diff --git a/lib/sys/exit.h b/lib/sys/exit.h
new file mode 100644
index 0000000..516d714
--- /dev/null
+++ b/lib/sys/exit.h
@@ -0,0 +1,11 @@
+#ifndef EXIT_H
+#define EXIT_H
+
+#include "syscalls.h"
+
+_Noreturn void exit(int error_code)
+{
+ syscall(EXIT, error_code);
+}
+
+#endif
diff --git a/lib/sys/fork.h b/lib/sys/fork.h
new file mode 100644
index 0000000..2ee3ae8
--- /dev/null
+++ b/lib/sys/fork.h
@@ -0,0 +1,10 @@
+#ifndef FORK_H
+#define FORK_H
+
+#include "syscalls.h"
+
+int fork() {
+ return syscall(FORK);
+}
+
+#endif
diff --git a/lib/sys/io.h b/lib/sys/io.h
new file mode 100644
index 0000000..3048ebe
--- /dev/null
+++ b/lib/sys/io.h
@@ -0,0 +1,11 @@
+#ifndef IO_H
+#define IO_H
+
+#include "write.h"
+#include "read.h"
+
+#define STDIN_FD 0
+#define STDOUT_FD 1
+#define STDERR_FD 2
+
+#endif
diff --git a/lib/sys/pipe.h b/lib/sys/pipe.h
new file mode 100644
index 0000000..f95f366
--- /dev/null
+++ b/lib/sys/pipe.h
@@ -0,0 +1,14 @@
+#ifndef PIPE_H
+#define PIPE_H
+
+#include "syscalls.h"
+
+#define PIPE_IN 1
+#define PIPE_OUT 0
+
+int pipe(int *filedes)
+{
+ return syscall(PIPE, filedes);
+}
+
+#endif
diff --git a/lib/sys/wait4.h b/lib/sys/wait4.h
new file mode 100644
index 0000000..e70539e
--- /dev/null
+++ b/lib/sys/wait4.h
@@ -0,0 +1,12 @@
+#ifndef WAIT4_H
+#define WAIT4_H
+
+#include "syscall.h"
+#include "sizes.h"
+
+int wait4(u64 pid, int *stat_addr, int options)
+{
+ return syscall(WAIT4, pid, stat_addr, options);
+}
+
+#endif
diff --git a/lib/sys/write.h b/lib/sys/write.h
index a705873..59f7789 100644
--- a/lib/sys/write.h
+++ b/lib/sys/write.h
@@ -4,7 +4,7 @@
#include "syscalls.h"
static int write(unsigned int fd, const char * buf, unsigned long count) {
- return syscall((void*)WRITE, (void*)fd, (void*)buf, (void*)count);
+ return syscall(WRITE, fd, buf, count);
}
#endif
diff --git a/smash/Makefile b/smash/Makefile
index 3f684cd..4deb244 100644
--- a/smash/Makefile
+++ b/smash/Makefile
@@ -1,5 +1,5 @@
unit_test_parser:
- gcc parser.c ../lib/cstr/cstr.c ../lib/malloc/malloc.c ../lib/sys/start.S -static -nostdlib -fno-stack-protector -o test -DPARSER_UNIT_TEST -g
+ gcc parser.c ../lib/cstr/cstr.c ../lib/malloc/malloc.c ../lib/sys/start.S -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -o test -DPARSER_UNIT_TEST -g
./test
unit_test_variables:
diff --git a/smash/parser.c b/smash/parser.c
index 33fb410..22b9ccf 100644
--- a/smash/parser.c
+++ b/smash/parser.c
@@ -14,21 +14,44 @@ expression_list_t *new_expression_from_line(char *line)
u64 n = cstr_split(line, '|');
char *current = line;
char *next = 0;
-
+ expression_list_t *head = 0;
+ expression_list_t *expression = 0;
for (; n > 0; --n) {
next = (char*)next_split(current);
strip_cstr(current, ' ');
- write(0, current, cstr_length(current));
- write(0, "\\n\n", 3);
+ if (!expression) {
+ expression = malloc(sizeof(expression_list_t));
+ head = expression;
+ } else {
+ expression->next = malloc(sizeof(expression_list_t));
+ expression = expression->next;
+ }
+
+ expression->call = current;
+ expression->next = 0;
current = next;
}
- return 0;
+
+ return head;
}
+
+void free_expression(expression_list_t *expression)
+{
+ expression_list_t *next;
+
+ while (expression) {
+ next = expression->next;
+ free(expression);
+ expression = next;
+ }
+}
+
+
char **__new_argv(char *exp)
{
u64 n = cstr_split(exp, ' ');
@@ -61,16 +84,54 @@ void __free_argv(char **argv)
#ifdef PARSER_UNIT_TEST
#include "../lib/sys/execve.h"
+#include "../lib/sys/fork.h"
+#include "../lib/sys/wait4.h"
+#include "../lib/sys/pipe.h"
+#include "../lib/sys/dup2.h"
+#include "../lib/sys/close.h"
+#include "../lib/sys/io.h"
+#include "../lib/sys/exit.h"
int main() {
- const char exp[] = "/bin/ls -a -l -h";
- char **argv = __new_argv(exp);
- char **p = argv;
- char *const envp[] = { 0 };
+ char in[] = "/bin/ls -a | /bin/wc -l";
+ expression_list_t *exps = new_expression_from_line(in);
+ expression_list_t *exp = exps;
+ char **envp = { 0 };
- execve(argv[0], argv, envp);
+ int pid[2];
+ int pipefd[2];
- free(argv);
+ char **argv1 = __new_argv(exp->call);
+ char **argv2 = __new_argv(exp->next->call);
+
+ pipe(pipefd);
+ pid[0] = fork();
+
+ if (pid[0] == 0) {
+ close(pipefd[0]);
+ dup2(pipefd[1], STDOUT_FD);
+ close(pipefd[1]);
+
+ execve(argv1[0], argv1, envp);
+ } else {
+ pid[1] = fork();
+
+
+ close(pipefd[1]);
+
+ if (pid[1] == 0) {
+ dup2(pipefd[0], STDIN_FD);
+ close(pipefd[0]);
+
+ execve(argv2[0], argv2, envp);
+ } else {
+ close(pipefd[0]);
+ wait4(pid[0], 0, 0);
+ wait4(pid[1], 0, 0);
+ }
+ }
+
+ return 0;
}
#endif
diff --git a/smash/parser.h b/smash/parser.h
index 9c23e0f..23eee88 100644
--- a/smash/parser.h
+++ b/smash/parser.h
@@ -3,13 +3,8 @@
#include "../lib/sys/sizes.h"
-typedef struct {
- const char *head;
- const char **args;
-} expression_t;
-
typedef struct expression_list_t__ {
- expression_t expression;
+ char *call;
struct expression_list_t__ *next;
} expression_list_t;
diff --git a/smash/test b/smash/test
new file mode 100755
index 0000000..a76addd
--- /dev/null
+++ b/smash/test
Binary files differ