summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init/main.c2
-rw-r--r--src/kernel/syscalls.c11
-rw-r--r--src/kernel/vfs/request.c1
-rw-r--r--src/kernel/vfs/request.h8
4 files changed, 13 insertions, 9 deletions
diff --git a/src/init/main.c b/src/init/main.c
index bed9ddb..265379d 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -46,7 +46,7 @@ void fs_test(void) {
// try reading
char buf[8];
- int len;
+ int len = 8;
for (int i = 0; i < 8; i++)
buf[i] = '.';
len = _syscall_read(file, buf, len);
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index d39aed9..a5c6f43 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -236,7 +236,16 @@ int _syscall_fs_respond(char __user *buf, int ret) {
struct vfs_request *req = process_current->handled_req;
if (!req) return -1;
- // TODO copy buffer
+ if (req->output.len > 0 && ret > 0) {
+ // if this vfsop outputs data and ret is positive, it's the length of the buffer
+ // TODO document
+ if (ret > req->output.len)
+ ret = req->output.len; // i'm not handling this in a special way - the fs server can prevent this on its own
+ if (!virt_cpy(req->caller->pages, req->output.buf,
+ process_current->pages, buf, ret)) {
+ // how should this error even be handled? TODO
+ }
+ }
process_current->handled_req = NULL;
vfs_request_finish(req, ret);
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index 9a51688..6159bbf 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -96,7 +96,6 @@ int vfs_request_finish(struct vfs_request *req, int ret) {
}
if (req->input.kern) kfree(req->input.buf_kern);
- if (req->output.kern) kfree(req->output.buf_kern);
req->caller->state = PS_RUNNING;
regs_savereturn(&req->caller->regs, ret);
diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h
index aabef4f..0ad50e9 100644
--- a/src/kernel/vfs/request.h
+++ b/src/kernel/vfs/request.h
@@ -18,7 +18,7 @@ struct vfs_backend {
// describes an in-process vfs call
struct vfs_request {
enum vfs_operation type;
- struct { // TODO maybe this should be a separate type
+ struct {
bool kern; // if false: use .buf ; if true: use .buf_kern
union {
char __user *buf;
@@ -27,11 +27,7 @@ struct vfs_request {
int len;
} input;
struct {
- bool kern; // if false: use .buf ; if true: use .buf_kern
- union {
- char __user *buf;
- char *buf_kern;
- };
+ char __user *buf;
int len;
} output;