summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/arch/i386/driver/ps2.c12
-rw-r--r--src/kernel/arch/i386/driver/ps2.h2
-rw-r--r--src/kernel/arch/i386/driver/serial.c15
-rw-r--r--src/kernel/arch/i386/driver/serial.h2
-rw-r--r--src/kernel/arch/i386/registers.h3
-rw-r--r--src/kernel/arch/i386/sysenter.c1
-rw-r--r--src/kernel/syscalls.c55
-rw-r--r--src/kernel/vfs/request.c26
-rw-r--r--src/kernel/vfs/request.h17
-rw-r--r--src/kernel/vfs/root.c8
-rw-r--r--src/kernel/vfs/root.h2
11 files changed, 74 insertions, 69 deletions
diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/i386/driver/ps2.c
index 666fa76..8955100 100644
--- a/src/kernel/arch/i386/driver/ps2.c
+++ b/src/kernel/arch/i386/driver/ps2.c
@@ -28,14 +28,15 @@ size_t ps2_read(uint8_t *buf, size_t len) {
return ring_get((void*)&backlog, buf, len);
}
-int vfs_ps2_accept(struct vfs_request *req) {
+void vfs_ps2_accept(struct vfs_request *req) {
// when you fix something here go also fix it in the COM1 driver
static uint8_t buf[32]; // pretty damn stupid
int ret;
switch (req->type) {
case VFSOP_OPEN:
// allows opening /ps2/anything, TODO don't
- return vfsreq_finish(req, 0); // fake file handle, whatever
+ vfsreq_finish(req, 0); // fake file handle, whatever
+ break;
case VFSOP_READ:
if (ps2_ready()) {
// TODO FUKKEN MESS
@@ -48,13 +49,14 @@ int vfs_ps2_accept(struct vfs_request *req) {
ret = ps2_read(buf, ret);
virt_cpy_to(req->caller->pages, req->output.buf, buf, ret);
} else ret = -1;
- return vfsreq_finish(req, ret);
+ vfsreq_finish(req, ret);
} else {
blocked_on = req;
- return -1;
}
+ break;
default:
- return vfsreq_finish(req, -1);
+ vfsreq_finish(req, -1);
+ break;
}
}
diff --git a/src/kernel/arch/i386/driver/ps2.h b/src/kernel/arch/i386/driver/ps2.h
index 1bbc2f1..c5d0ce1 100644
--- a/src/kernel/arch/i386/driver/ps2.h
+++ b/src/kernel/arch/i386/driver/ps2.h
@@ -8,5 +8,5 @@ bool ps2_ready(void);
void ps2_recv(uint8_t scancode);
size_t ps2_read(uint8_t *buf, size_t max_len);
-int vfs_ps2_accept(struct vfs_request *);
+void vfs_ps2_accept(struct vfs_request *);
bool vfs_ps2_ready(struct vfs_backend *);
diff --git a/src/kernel/arch/i386/driver/serial.c b/src/kernel/arch/i386/driver/serial.c
index 4e274d8..170cc4d 100644
--- a/src/kernel/arch/i386/driver/serial.c
+++ b/src/kernel/arch/i386/driver/serial.c
@@ -69,12 +69,13 @@ void serial_write(const char *buf, size_t len) {
}
-int vfs_com1_accept(struct vfs_request *req) {
+void vfs_com1_accept(struct vfs_request *req) {
static uint8_t buf[32];
int ret;
switch (req->type) {
case VFSOP_OPEN:
- return vfsreq_finish(req, 0);
+ vfsreq_finish(req, 0);
+ break;
case VFSOP_READ:
if (serial_ready()) {
if (req->caller) {
@@ -86,11 +87,11 @@ int vfs_com1_accept(struct vfs_request *req) {
ret = serial_read(buf, ret);
virt_cpy_to(req->caller->pages, req->output.buf, buf, ret);
} else ret = -1;
- return vfsreq_finish(req, ret);
+ vfsreq_finish(req, ret);
} else {
blocked_on = req;
- return -1;
}
+ break;
case VFSOP_WRITE:
if (req->caller) {
struct virt_iter iter;
@@ -100,9 +101,11 @@ int vfs_com1_accept(struct vfs_request *req) {
serial_write(iter.frag, iter.frag_len);
ret = iter.prior;
} else ret = -1;
- return vfsreq_finish(req, ret);
+ vfsreq_finish(req, ret);
+ break;
default:
- return vfsreq_finish(req, -1);
+ vfsreq_finish(req, -1);
+ break;
}
}
diff --git a/src/kernel/arch/i386/driver/serial.h b/src/kernel/arch/i386/driver/serial.h
index e7f9b7c..6aff142 100644
--- a/src/kernel/arch/i386/driver/serial.h
+++ b/src/kernel/arch/i386/driver/serial.h
@@ -11,5 +11,5 @@ size_t serial_read(char *buf, size_t len);
void serial_write(const char *buf, size_t len);
-int vfs_com1_accept(struct vfs_request *);
+void vfs_com1_accept(struct vfs_request *);
bool vfs_com1_ready(struct vfs_backend *);
diff --git a/src/kernel/arch/i386/registers.h b/src/kernel/arch/i386/registers.h
index 8bd090d..9f481d3 100644
--- a/src/kernel/arch/i386/registers.h
+++ b/src/kernel/arch/i386/registers.h
@@ -14,7 +14,8 @@ struct registers {
} __attribute__((__packed__));
// saves a return value according to the SysV ABI
-static inline void regs_savereturn(struct registers *regs, uint64_t value) {
+static inline uint64_t regs_savereturn(struct registers *regs, uint64_t value) {
regs->eax = value;
regs->edx = value >> 32;
+ return value;
}
diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/i386/sysenter.c
index 1d2a333..71dfbe9 100644
--- a/src/kernel/arch/i386/sysenter.c
+++ b/src/kernel/arch/i386/sysenter.c
@@ -23,6 +23,5 @@ _Noreturn void sysenter_stage2(void) {
val = _syscall(regs->eax, regs->ebx,
regs->esi, regs->edi, (uintptr_t)regs->ebp);
- regs_savereturn(&process_current->regs, val);
process_switch_any();
}
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index c5e25b7..aa2d45f 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -9,6 +9,8 @@
#include <shared/syscalls.h>
#include <stdint.h>
+#define SYSCALL_RETURN(val) return regs_savereturn(&process_current->regs, val)
+
_Noreturn void _syscall_exit(int ret) {
process_kill(process_current, ret);
process_switch_any();
@@ -22,23 +24,23 @@ int _syscall_await(void) {
for (struct process *iter = process_current->child;
iter; iter = iter->sibling) {
if (iter->state == PS_DEAD && !iter->noreap)
- return process_try2collect(iter);
+ SYSCALL_RETURN(process_try2collect(iter));
if (iter->state != PS_DEADER)
has_children = true;
}
if (!has_children) {
process_transition(process_current, PS_RUNNING);
- return ~0; // TODO errno
+ SYSCALL_RETURN(~0); // TODO errno
} else {
- return -1;
+ SYSCALL_RETURN(-1);
}
}
int _syscall_fork(int flags) {
struct process *child = process_fork(process_current, flags);
regs_savereturn(&child->regs, 0);
- return 1;
+ SYSCALL_RETURN(1);
}
handle_t _syscall_open(const char __user *path, int len) {
@@ -46,9 +48,9 @@ handle_t _syscall_open(const char __user *path, int len) {
char *path_buf = NULL;
if (PATH_MAX < len)
- return -1;
+ SYSCALL_RETURN(-1);
if (process_find_handle(process_current, 0) < 0)
- return -1;
+ SYSCALL_RETURN(-1);
path_buf = virt_cpy2kmalloc(process_current->pages, path, len);
if (!path_buf) goto fail;
@@ -66,7 +68,7 @@ handle_t _syscall_open(const char __user *path, int len) {
memcpy(path_buf, path_buf + mount->prefix_len, len);
}
- return vfsreq_create((struct vfs_request) {
+ vfsreq_create((struct vfs_request) {
.type = VFSOP_OPEN,
.input = {
.kern = true,
@@ -76,9 +78,10 @@ handle_t _syscall_open(const char __user *path, int len) {
.caller = process_current,
.backend = mount->backend,
});
+ return -1; // dummy
fail:
kfree(path_buf);
- return -1;
+ SYSCALL_RETURN(-1);
}
int _syscall_mount(handle_t hid, const char __user *path, int len) {
@@ -86,7 +89,8 @@ int _syscall_mount(handle_t hid, const char __user *path, int len) {
struct vfs_backend *backend = NULL;
char *path_buf = NULL;
- if (PATH_MAX < len) return -1;
+ if (PATH_MAX < len)
+ SYSCALL_RETURN(-1);
// copy the path to the kernel to simplify it
path_buf = virt_cpy2kmalloc(process_current->pages, path, len);
@@ -122,18 +126,18 @@ int _syscall_mount(handle_t hid, const char __user *path, int len) {
kmalloc_sanity(mount);
kmalloc_sanity(mount->prefix);
- return 0;
+ SYSCALL_RETURN(0);
fail:
kfree(path_buf);
kfree(mount);
- return -1;
+ SYSCALL_RETURN(-1);
}
int _syscall_read(handle_t handle_num, void __user *buf, size_t len, int offset) {
struct handle *handle = process_handle_get(process_current, handle_num, HANDLE_FILE);
- if (!handle) return -1;
- return vfsreq_create((struct vfs_request) {
+ if (!handle) SYSCALL_RETURN(-1);
+ vfsreq_create((struct vfs_request) {
.type = VFSOP_READ,
.output = {
.buf = (userptr_t) buf,
@@ -144,12 +148,13 @@ int _syscall_read(handle_t handle_num, void __user *buf, size_t len, int offset)
.caller = process_current,
.backend = handle->file.backend,
});
+ return -1; // dummy
}
int _syscall_write(handle_t handle_num, const void __user *buf, size_t len, int offset) {
struct handle *handle = process_handle_get(process_current, handle_num, HANDLE_FILE);
- if (!handle) return -1;
- return vfsreq_create((struct vfs_request) {
+ if (!handle) SYSCALL_RETURN(-1);
+ vfsreq_create((struct vfs_request) {
.type = VFSOP_WRITE,
.input = {
.buf = (userptr_t) buf,
@@ -160,15 +165,16 @@ int _syscall_write(handle_t handle_num, const void __user *buf, size_t len, int
.caller = process_current,
.backend = handle->file.backend,
});
+ return -1; // dummy
}
int _syscall_close(handle_t hid) {
if (hid < 0 || hid >= HANDLE_MAX) return -1;
struct handle **h = &process_current->handles[hid];
- if (!*h) return -1;
+ if (!*h) SYSCALL_RETURN(-1);
handle_close(*h);
*h = NULL;
- return 0;
+ SYSCALL_RETURN(0);
}
handle_t _syscall_fs_fork2(void) {
@@ -177,7 +183,7 @@ handle_t _syscall_fs_fork2(void) {
handle_t front;
front = process_find_handle(process_current, 1);
- if (front < 0) return -1;
+ if (front < 0) SYSCALL_RETURN(-1);
process_current->handles[front] = handle_init(HANDLE_FS_FRONT);
backend = kmalloc(sizeof *backend); // TODO never freed
@@ -193,12 +199,12 @@ handle_t _syscall_fs_fork2(void) {
regs_savereturn(&child->regs, 0);
process_current->handles[front]->fs.backend = backend;
- return front;
+ SYSCALL_RETURN(front);
}
int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __user *res) {
struct vfs_backend *backend = process_current->controlled;
- if (!backend) return -1;
+ if (!backend) SYSCALL_RETURN(-1);
process_transition(process_current, PS_WAITS4REQUEST);
assert(!backend->user.handler); // TODO allow multiple processes to wait on the same backend
@@ -209,12 +215,13 @@ int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __us
process_current->awaited_req.max_len = max_len;
process_current->awaited_req.res = res;
- return vfs_backend_tryaccept(backend);
+ vfs_backend_tryaccept(backend); // sets return value
+ return -1; // dummy
}
int _syscall_fs_respond(char __user *buf, int ret) {
struct vfs_request *req = process_current->handled_req;
- if (!req) return -1;
+ if (!req) SYSCALL_RETURN(-1);
if (req->output.len > 0 && ret > 0) {
// if this vfsop outputs data and ret is positive, it's the length of the buffer
@@ -228,7 +235,7 @@ int _syscall_fs_respond(char __user *buf, int ret) {
process_current->handled_req = NULL;
vfsreq_finish(req, ret);
- return 0;
+ SYSCALL_RETURN(0);
}
int _syscall_memflag(void __user *addr, size_t len, int flags) {
@@ -247,7 +254,7 @@ int _syscall_memflag(void __user *addr, size_t len, int flags) {
}
}
- return -1;
+ SYSCALL_RETURN(-1);
}
int _syscall(int num, int a, int b, int c, int d) {
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index f463b86..3e7c9f0 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -6,7 +6,7 @@
#include <kernel/vfs/root.h>
#include <shared/mem.h>
-int vfsreq_create(struct vfs_request req_) {
+void vfsreq_create(struct vfs_request req_) {
struct vfs_request *req = kmalloc(sizeof *req); // freed in vfsreq_finish
memcpy(req, &req_, sizeof *req);
@@ -19,17 +19,17 @@ int vfsreq_create(struct vfs_request req_) {
}
if (!req->backend || !req->backend->potential_handlers)
- return vfsreq_finish(req, -1);
+ vfsreq_finish(req, -1);
struct vfs_request **iter = &req->backend->queue;
while (*iter != NULL) // find free spot in queue
iter = &(*iter)->queue_next;
*iter = req;
- return vfs_backend_tryaccept(req->backend);
+ vfs_backend_tryaccept(req->backend);
}
-int vfsreq_finish(struct vfs_request *req, int ret) {
+void vfsreq_finish(struct vfs_request *req, int ret) {
if (req->type == VFSOP_OPEN && ret >= 0) {
// open() calls need special handling
// we need to wrap the id returned by the VFS in a handle passed to
@@ -63,32 +63,32 @@ int vfsreq_finish(struct vfs_request *req, int ret) {
vfs_backend_refdown(req->backend);
kfree(req);
- return ret;
+ return;
}
-int vfs_backend_tryaccept(struct vfs_backend *backend) {
+void vfs_backend_tryaccept(struct vfs_backend *backend) {
struct vfs_request *req = backend->queue;
- if (!req) return -1;
+ if (!req) return;
/* ensure backend is ready to accept request */
if (backend->is_user) {
- if (!backend->user.handler) return -1;
+ if (!backend->user.handler) return;
} else {
assert(backend->kern.ready);
- if (!backend->kern.ready(backend)) return -1;
+ if (!backend->kern.ready(backend)) return;
}
backend->queue = req->queue_next;
if (backend->is_user) {
- return vfs_backend_user_accept(req);
+ vfs_backend_user_accept(req);
} else {
assert(backend->kern.accept);
- return backend->kern.accept(req);
+ backend->kern.accept(req);
}
}
-int vfs_backend_user_accept(struct vfs_request *req) {
+void vfs_backend_user_accept(struct vfs_request *req) {
struct process *handler;
struct fs_wait_response res = {0};
int len = 0;
@@ -123,7 +123,7 @@ int vfs_backend_user_accept(struct vfs_request *req) {
handler->handled_req = req;
req->backend->user.handler = NULL;
regs_savereturn(&handler->regs, 0);
- return 0;
+ return;
fail:
panic_unimplemented(); // TODO
}
diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h
index b4624fa..9dc6088 100644
--- a/src/kernel/vfs/request.h
+++ b/src/kernel/vfs/request.h
@@ -25,10 +25,7 @@ struct vfs_backend {
} user;
struct {
bool (*ready)(struct vfs_backend *);
-
- // return value might be passed to caller
- // TODO make return void
- int (*accept)(struct vfs_request *);
+ void (*accept)(struct vfs_request *);
} kern;
};
};
@@ -59,13 +56,11 @@ struct vfs_request {
};
/** Assigns the vfs_request to the caller, and dispatches the call */
-int vfsreq_create(struct vfs_request);
-int vfsreq_finish(struct vfs_request *, int ret);
+void vfsreq_create(struct vfs_request);
+void vfsreq_finish(struct vfs_request *, int ret);
-/** Try to accept an enqueued request
- * @return same as _syscall_fs_wait, passed to it. except on calls to kern backend, where it returns the result of the fs op - also gets directly passed to caller. it's a mess */
-// TODO fix the return value mess
-int vfs_backend_tryaccept(struct vfs_backend *);
-int vfs_backend_user_accept(struct vfs_request *req);
+/** Try to accept an enqueued request */
+void vfs_backend_tryaccept(struct vfs_backend *);
+void vfs_backend_user_accept(struct vfs_request *req);
void vfs_backend_refdown(struct vfs_backend *);
diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c
index c7bd717..989c77e 100644
--- a/src/kernel/vfs/root.c
+++ b/src/kernel/vfs/root.c
@@ -130,17 +130,15 @@ static int handle(struct vfs_request *req, bool *ready) {
}
}
-int vfs_root_accept(struct vfs_request *req) {
+void vfs_root_accept(struct vfs_request *req) {
if (req->caller) {
bool ready = true;
int ret = handle(req, &ready);
if (ready) {
- return vfsreq_finish(req, ret);
- } else {
- return -1;
+ vfsreq_finish(req, ret);
}
} else {
- return vfsreq_finish(req, -1);
+ vfsreq_finish(req, -1);
}
}
diff --git a/src/kernel/vfs/root.h b/src/kernel/vfs/root.h
index f10fb85..3db958d 100644
--- a/src/kernel/vfs/root.h
+++ b/src/kernel/vfs/root.h
@@ -1,5 +1,5 @@
#pragma once
#include <kernel/vfs/request.h>
-int vfs_root_accept(struct vfs_request *);
+void vfs_root_accept(struct vfs_request *);
bool vfs_root_ready(struct vfs_backend *);