From 206ca77636cca94d14d7486a7a0e2679bf107a28 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Thu, 16 Sep 2021 06:33:26 +0000
Subject: fs_read stub, basic implementation in userland

---
 src/init/main.c       | 13 +++++++++++++
 src/kernel/syscalls.c | 17 ++++++++++++++---
 src/shared/flags.h    |  1 +
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/init/main.c b/src/init/main.c
index 15afaf5..bed9ddb 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -43,6 +43,14 @@ void fs_test(void) {
 	file = _syscall_open(argify("/mnt/tty"));
 	log("open returned. ");
 	_syscall_write(file, argify("hello"));
+
+	// try reading
+	char buf[8];
+	int len;
+	for (int i = 0; i < 8; i++)
+		buf[i] = '.';
+	len = _syscall_read(file, buf, len);
+	_syscall_write(tty_fd, buf, len + 1); // read 1 byte past, should be a dot
 }
 
 void fs_server(handle_t back) {
@@ -57,6 +65,11 @@ void fs_server(handle_t back) {
 				_syscall_fs_respond(NULL, 32); // doesn't check the path yet
 				break;
 
+			case VFSOP_READ:
+				// all reads output "world"
+				_syscall_fs_respond("world", 5);
+				break;
+
 			case VFSOP_WRITE:
 				// uppercase the buffer
 				for (int i = 0; i < len; i++) buf[i] &= ~id; // id == 32
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 48e67db..d39aed9 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -135,9 +135,20 @@ fail:
 	return -1;
 }
 
-int _syscall_read(handle_t handle, char __user *buf, int len) {
-	if (handle < 0 || handle >= HANDLE_MAX) return -1;
-	return -1;
+int _syscall_read(handle_t handle_num, char __user *buf, int len) {
+	struct handle *handle = &process_current->handles[handle_num];
+	if (handle_num < 0 || handle_num >= HANDLE_MAX) return -1;
+	if (handle->type != HANDLE_FILE) return -1;
+	return vfs_request_create((struct vfs_request) {
+			.type = VFSOP_READ,
+			.output = {
+				.buf = (userptr_t) buf,
+				.len = len,
+			},
+			.id = handle->file.id,
+			.caller = process_current,
+			.backend = handle->file.backend,
+		});
 }
 
 int _syscall_write(handle_t handle_num, const char __user *buf, int len) {
diff --git a/src/shared/flags.h b/src/shared/flags.h
index 3f182b9..eced61f 100644
--- a/src/shared/flags.h
+++ b/src/shared/flags.h
@@ -2,6 +2,7 @@
 
 enum vfs_operation {
 	VFSOP_OPEN,
+	VFSOP_READ,
 	VFSOP_WRITE,
 };
 
-- 
cgit v1.2.3