From ac74cec51fa9c31e4c8cea2dd9f01b7b895d61b4 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Sun, 22 Aug 2021 13:40:22 +0200
Subject: fs_open() stub

---
 src/init/main.c       | 24 +++---------------------
 src/init/syscalls.c   |  4 ++++
 src/kernel/syscalls.c | 25 +++++++++++++++++++++++++
 src/kernel/syscalls.h |  6 ++++++
 src/kernel/vfs/path.h |  2 ++
 5 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/src/init/main.c b/src/init/main.c
index fb379d2..51764ce 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -14,27 +14,9 @@ const char *multipageify(const char *str) {
 }
 
 int main() {
-	char buf[64];
-	int len = 64;
-
-	// try to print a string crossing page boundaries
-	_syscall_debuglog(
-		multipageify("I cross pages. "),
-		      sizeof("I cross pages. ") - 1);
-
-	if (_syscall_fork() > 0) {
-		_syscall_debuglog("parent ",
-		           sizeof("parent ") - 1);
-
-		len = _syscall_await(buf, 64);
-		_syscall_debuglog(buf, len);
-	} else {
-		_syscall_debuglog("child ",
-		           sizeof("child ") - 1);
-		_syscall_exit(
-			multipageify("this is the child's exit message!"),
-			      sizeof("this is the child's exit message!") - 1);
-	}
+	_syscall_fs_open(
+			multipageify("/some/../path"),
+			      sizeof("/some/../path") - 1);
 
 	_syscall_exit("bye from init! ",
 	       sizeof("bye from init! ") - 1);
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index 1e11705..b0e1587 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -16,6 +16,10 @@ int _syscall_await(char *buf, int len) {
 	return _syscall(_SYSCALL_AWAIT, (int)buf, (int)len, 0);
 }
 
+fd_t _syscall_fs_open(const char *path, size_t len) {
+	return _syscall(_SYSCALL_FS_OPEN, (int)path, len, 0);
+}
+
 int _syscall_debuglog(const char *msg, size_t len) {
 	return _syscall(_SYSCALL_DEBUGLOG, (int)msg, len, 0);
 }
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 2b3dafc..13e0535 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -3,6 +3,7 @@
 #include <kernel/panic.h>
 #include <kernel/proc.h>
 #include <kernel/syscalls.h>
+#include <kernel/vfs/path.h>
 #include <stdint.h>
 
 _Noreturn static void await_finish(struct process *dead, struct process *listener) {
@@ -64,6 +65,28 @@ int _syscall_fork() {
 	return 1;
 }
 
+fd_t _syscall_fs_open(const char *path, size_t len) {
+	struct virt_iter iter;
+	static char buffer[PATH_MAX]; // holds the simplified path
+	size_t pos = 0;
+
+	if (len > PATH_MAX) return -1;
+
+	// copy the path to buffer
+	virt_iter_new(&iter, (void*)path, len, process_current->pages, true, false);
+	while (virt_iter_next(&iter)) {
+		memcpy(buffer + pos, iter.frag, iter.frag_len);
+		pos += iter.frag_len;
+	}
+	if (iter.error) return -1;
+
+	len = path_simplify(buffer, buffer, len);
+	if (len < 0) return -1;
+
+	tty_write(buffer, len);
+	return -1;
+}
+
 int _syscall_debuglog(const char *msg, size_t len) {
 	struct virt_iter iter;
 	size_t written = 0;
@@ -84,6 +107,8 @@ int syscall_handler(int num, int a, int b, int c) {
 			return _syscall_await((void*)a, b);
 		case _SYSCALL_FORK:
 			return _syscall_fork();
+		case _SYSCALL_FS_OPEN:
+			return _syscall_fs_open((void*)a, b);
 		case _SYSCALL_DEBUGLOG:
 			return _syscall_debuglog((void*)a, b);
 		default:
diff --git a/src/kernel/syscalls.h b/src/kernel/syscalls.h
index 83a68b2..5f55454 100644
--- a/src/kernel/syscalls.h
+++ b/src/kernel/syscalls.h
@@ -2,12 +2,16 @@
 #pragma once
 #include <stddef.h>
 
+typedef int fd_t;
+
 enum {
 	// idc about stable syscall numbers just yet
 	_SYSCALL_EXIT,
 	_SYSCALL_AWAIT,
 	_SYSCALL_FORK,
 
+	_SYSCALL_FS_OPEN,
+
 	_SYSCALL_DEBUGLOG
 };
 
@@ -27,6 +31,8 @@ int _syscall_await(char *buf, int len);
  */
 int _syscall_fork();
 
+fd_t _syscall_fs_open(const char *path, size_t len);
+
 /** Prints a message to the debug console.
  * @return the amount of bytes written (can be less than len)
  */
diff --git a/src/kernel/vfs/path.h b/src/kernel/vfs/path.h
index 769aa27..8efa0d4 100644
--- a/src/kernel/vfs/path.h
+++ b/src/kernel/vfs/path.h
@@ -1,6 +1,8 @@
 #pragma once
 #include <stddef.h>
 
+#define PATH_MAX 512
+
 /** Reduce a path to its simplest form.
  *
  * @return length of the string in *out, always less than len. Negative if the path was invalid.
-- 
cgit v1.2.3