summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2021-09-05 15:32:00 +0200
committerdzwdz2021-09-05 15:32:00 +0200
commitf229b2e8a6ca840af8f3ac26cc2f412891a99a5e (patch)
treeeafe7e435cc011b0b1e8cdf396f3e6b27f6a4ee3 /src
parent613de4db61dd99e7d2049b0a303e167fa711030b (diff)
root vfs: implement writing to /tty
Diffstat (limited to 'src')
-rw-r--r--src/kernel/syscalls.c14
-rw-r--r--src/kernel/vfs/backend.c1
-rw-r--r--src/kernel/vfs/root.c24
-rw-r--r--src/shared/vfs.h9
4 files changed, 42 insertions, 6 deletions
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 8f520ab..4718b4b 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -141,8 +141,18 @@ int _syscall_fd_read(handle_t handle, user_ptr buf, int len) {
return -1;
}
-int _syscall_fd_write(handle_t handle, user_ptr buf, int len) {
- if (handle < 0 || handle >= HANDLE_MAX) return -1;
+int _syscall_fd_write(handle_t handle_num, user_ptr 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;
+ vfs_backend_dispatch(handle->file.backend, (struct vfs_op) {
+ .type = VFSOP_WRITE,
+ .rw = {
+ .buf = buf,
+ .buf_len = len,
+ .id = handle->file.id,
+ }
+ });
return -1;
}
diff --git a/src/kernel/vfs/backend.c b/src/kernel/vfs/backend.c
index cf73ef0..9a2b777 100644
--- a/src/kernel/vfs/backend.c
+++ b/src/kernel/vfs/backend.c
@@ -8,6 +8,7 @@ _Noreturn void vfs_backend_dispatch(struct vfs_backend *backend, struct vfs_op o
struct vfs_op_request req = {
.op = op,
.caller = process_current,
+ .backend = backend,
};
switch (backend->type) {
case VFS_BACK_ROOT:
diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c
index c90557b..0f11a5b 100644
--- a/src/kernel/vfs/root.c
+++ b/src/kernel/vfs/root.c
@@ -1,6 +1,9 @@
-#include <kernel/vfs/root.h>
-#include <kernel/util.h>
+#include <kernel/mem.h>
#include <kernel/panic.h>
+#include <kernel/proc.h>
+#include <kernel/types.h>
+#include <kernel/util.h>
+#include <kernel/vfs/root.h>
int vfs_root_handler(struct vfs_op_request *req) {
switch (req->op.type) {
@@ -10,7 +13,20 @@ int vfs_root_handler(struct vfs_op_request *req) {
return 0;
}
return -1;
- default:
- panic();
+ case VFSOP_WRITE:
+ switch (req->op.rw.id) {
+ // every id corresponds to a special file type
+ // this is a shit way to do this but :shrug:
+ case 0: { // tty
+ struct virt_iter iter;
+ virt_iter_new(&iter, req->op.rw.buf, req->op.rw.buf_len,
+ req->caller->pages, true, false);
+ while (virt_iter_next(&iter))
+ tty_write(iter.frag, iter.frag_len);
+ return iter.prior;
+ }
+ default: panic();
+ }
+ default: panic();
}
}
diff --git a/src/shared/vfs.h b/src/shared/vfs.h
index 1d4812d..d88c424 100644
--- a/src/shared/vfs.h
+++ b/src/shared/vfs.h
@@ -5,8 +5,12 @@
enum vfs_op_types {
VFSOP_OPEN,
+ VFSOP_WRITE,
};
+/* currently, this struct is fully created in kernelspace
+ * i might add a syscall which allows a process to just pass it raw, with some
+ * validation - so keep that in mind */
struct vfs_op {
enum vfs_op_types type;
union {
@@ -14,5 +18,10 @@ struct vfs_op {
const char *path;
int path_len;
} open;
+ struct {
+ user_ptr buf;
+ int buf_len;
+ int id; // filled in by the kernel
+ } rw;
};
};