summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/arch/amd64/driver/util.h1
-rw-r--r--src/kernel/syscalls.c2
-rw-r--r--src/kernel/vfs/procfs.c8
-rw-r--r--src/kernel/vfs/request.c4
4 files changed, 8 insertions, 7 deletions
diff --git a/src/kernel/arch/amd64/driver/util.h b/src/kernel/arch/amd64/driver/util.h
index 4b8bb04..c49b859 100644
--- a/src/kernel/arch/amd64/driver/util.h
+++ b/src/kernel/arch/amd64/driver/util.h
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stddef.h>
+// TODO put req_readcopy in a global header
int req_readcopy(VfsReq *req, const void *buf, size_t len);
/* compare request path. path MUST be a static string */
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 66f8757..ebdf64e 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -295,7 +295,7 @@ long _sys_fs_respond(hid_t hid, const void __user *buf, long ret, int flags) {
if (!h || h->type != HANDLE_FS_REQ) SYSCALL_RETURN(-EBADF);
VfsReq *req = h->req;
if (req) {
- if (req->output.len > 0 && ret > 0) {
+ if (ret > 0 && req->type == VFSOP_READ) {
// if this vfsop outputs data and ret is positive, it's the length of the buffer
// TODO document
// TODO move to vfsreq_finish
diff --git a/src/kernel/vfs/procfs.c b/src/kernel/vfs/procfs.c
index 7669b78..fc17f1d 100644
--- a/src/kernel/vfs/procfs.c
+++ b/src/kernel/vfs/procfs.c
@@ -1,4 +1,5 @@
#include <camellia/errno.h>
+#include <kernel/arch/amd64/driver/util.h> // portable despite the name
#include <kernel/malloc.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
@@ -119,10 +120,6 @@ procfs_accept(VfsReq *req)
if (req->type == VFSOP_READ && (h->type == PhDir || h->type == PhRoot)) {
// TODO port dirbuild to kernel
int pos = 0;
- if (req->offset != 0) {
- vfsreq_finish_short(req, -ENOSYS);
- return;
- }
if (h->type == PhDir) {
pos += snprintf(buf + pos, 512 - pos, "intr")+1;
pos += snprintf(buf + pos, 512 - pos, "mem")+1;
@@ -136,8 +133,7 @@ procfs_accept(VfsReq *req)
}
}
assert(0 <= pos && (size_t)pos <= sizeof buf);
- pcpy_to(req->caller, req->output.buf, buf, pos);
- vfsreq_finish_short(req, pos);
+ vfsreq_finish_short(req, req_readcopy(req, buf, pos));
} else if (req->type == VFSOP_READ && h->type == PhMem) {
if (p->pages == NULL || req->caller->pages == NULL) {
vfsreq_finish_short(req, 0);
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index 410e41e..5723201 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -73,6 +73,10 @@ void vfsreq_finish(VfsReq *req, char __user *stored, long ret,
}
}
+ if (req->type == VFSOP_READ && ret >= 0) {
+ assert((size_t)ret <= req->output.len);
+ }
+
if (req->input.kern)
kfree(req->input.buf_kern);