diff options
-rw-r--r-- | src/kernel/syscalls.c | 95 |
1 files changed, 54 insertions, 41 deletions
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 0b22770..0730620 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -164,13 +164,7 @@ hid_t _sys_dup(hid_t from, hid_t to, int flags) { SYSCALL_RETURN(hs_dup(proc_cur->hs, from, to, flags)); } -static long simple_vfsop( - enum vfs_op vfsop, hid_t hid, void __user *buf, - size_t len, long offset, int flags) -{ - assert(vfsop == VFSOP_READ - || vfsop == VFSOP_WRITE - || vfsop == VFSOP_GETSIZE); +long _sys_read(hid_t hid, void __user *buf, size_t len, long offset) { Handle *h = hs_get(proc_cur->hs, hid); if (!h) { SYSCALL_RETURN(-EBADF); @@ -178,56 +172,75 @@ static long simple_vfsop( if (h->type != HANDLE_FILE && h->type != HANDLE_PIPE) { SYSCALL_RETURN(-ENOSYS); } - - // TODO those checks really need some comprehensive tests - if (vfsop == VFSOP_READ && !h->readable) - SYSCALL_RETURN(-EACCES); - if (vfsop == VFSOP_WRITE && !h->writeable) + if (!h->readable) { SYSCALL_RETURN(-EACCES); - + } if (h->type == HANDLE_FILE) { - VfsReq req = (VfsReq){ - .type = vfsop, + vfsreq_dispatchcopy((VfsReq) { + .type = VFSOP_READ, .backend = h->backend, .id = h->file_id, .caller = proc_cur, .offset = offset, - .flags = flags, - }; - if (vfsop == VFSOP_READ) { - req.out = buf; - req.outlen = len; - } - if (vfsop == VFSOP_WRITE) { - req.uin = buf; - req.uinlen = len; - } - vfsreq_dispatchcopy(req); - } else if (h->type == HANDLE_PIPE) { - if (vfsop == VFSOP_READ || vfsop == VFSOP_WRITE) { - /* already checked if this is the correct pipe end */ - pipe_joinqueue(h, proc_cur, buf, len); - } else SYSCALL_RETURN(-ENOSYS); - } else { - panic_invalid_state(); + .out = buf, + .outlen = len, + }); + } else { /* h->type == HANDLE_PIPE */ + /* we already know this is the correct pipe end as it's readable */ + pipe_joinqueue(h, proc_cur, buf, len); } return 0; } -long _sys_read(hid_t hid, void __user *buf, size_t len, long offset) { - simple_vfsop(VFSOP_READ, hid, buf, len, offset, 0); - return 0; -} - long _sys_write(hid_t hid, const void __user *buf, size_t len, long offset, int flags) { - if (flags & ~(WRITE_TRUNCATE)) + Handle *h = hs_get(proc_cur->hs, hid); + if (flags & ~(WRITE_TRUNCATE)) { SYSCALL_RETURN(-ENOSYS); - simple_vfsop(VFSOP_WRITE, hid, (userptr_t)buf, len, offset, flags); + } + if (!h) { + SYSCALL_RETURN(-EBADF); + } + if (h->type != HANDLE_FILE && h->type != HANDLE_PIPE) { + SYSCALL_RETURN(-ENOSYS); + } + if (!h->writeable) { + SYSCALL_RETURN(-EACCES); + } + if (h->type == HANDLE_FILE) { + vfsreq_dispatchcopy((VfsReq) { + .type = VFSOP_WRITE, + .backend = h->backend, + .id = h->file_id, + .caller = proc_cur, + .offset = offset, + .flags = flags, + .uin = (void __user*)buf, // TODO why isn't this const + .uinlen = len, + }); + } else { /* h->type == HANDLE_PIPE */ + /* we already know this is the correct pipe end as it's writeable */ + pipe_joinqueue(h, proc_cur, (void __user*)buf, len); + } return 0; } long _sys_getsize(hid_t hid) { - simple_vfsop(VFSOP_GETSIZE, hid, NULL, 0, 0, 0); + Handle *h = hs_get(proc_cur->hs, hid); + if (!h) { + SYSCALL_RETURN(-EBADF); + } + if (h->type != HANDLE_FILE) { + SYSCALL_RETURN(-ENOSYS); + } + if (!h->readable && !h->writeable) { /* is this even possible? */ + SYSCALL_RETURN(-EACCES); + } + vfsreq_dispatchcopy((VfsReq) { + .type = VFSOP_GETSIZE, + .backend = h->backend, + .id = h->file_id, + .caller = proc_cur, + }); return 0; } |