From 1fc2d9c88af77c3af81b6bd461e6b019b97d2dbb Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sat, 20 Jul 2024 23:17:36 +0200 Subject: *: moving files --- src/kernel/handle.h | 1 + src/kernel/syscalls.c | 32 ++++++++++++++++++++++++++++++++ src/kernel/vfs/request.c | 1 + src/kernel/vfs/request.h | 4 +--- 4 files changed, 35 insertions(+), 3 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/handle.h b/src/kernel/handle.h index af9d45a..abbfa68 100644 --- a/src/kernel/handle.h +++ b/src/kernel/handle.h @@ -19,6 +19,7 @@ struct Handle { enum handle_type type; VfsBackend *backend; /* HANDLE_FILE | HANDLE_FS_FRONT */ void __user *file_id; /* only applicable to HANDLE_FILE */ + // TODO store flags instead bool readable, writeable; /* HANDLE_FILE | HANDLE_PIPE */ VfsReq *req; /* HANDLE_FS_REQ */ struct { diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 3fc09fa..23a8883 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -456,6 +456,37 @@ hid_t _sys_getnull(int flags) { SYSCALL_RETURN((0 <= hid) ? hid : -EMFILE); } +long _sys_duplex(hid_t from, hid_t to, int flags) { + if ((flags & ~DUPLEX_REMOVE) != 0) { + SYSCALL_RETURN(-ENOSYS); + } + + Handle *fromh = hs_get(proc_cur->hs, from); + Handle *toh = hs_get(proc_cur->hs, to); + if (fromh == NULL || toh == NULL) { + SYSCALL_RETURN(-EBADF); + } + if (fromh->type != HANDLE_FILE || toh->type != HANDLE_FILE) { + SYSCALL_RETURN(-ENOSYS); + } + if (fromh->backend != toh->backend) { + SYSCALL_RETURN(-ENOSYS); + } + if (!fromh->readable || !fromh->writeable || !toh->writeable) { + SYSCALL_RETURN(-EACCES); + } + + vfsreq_dispatchcopy((VfsReq) { + .type = VFSOP_DUPLEX, + .id = fromh->file_id, + .id2 = toh->file_id, + .flags = flags, + .caller = proc_cur, + .backend = fromh->backend, + }); + return -1; // dummy +} + long _sys_execbuf(void __user *ubuf, size_t len) { if (len == 0) SYSCALL_RETURN(0); static_assert(EXECBUF_MAX_LEN <= KMALLOC_MAX); @@ -512,6 +543,7 @@ long _syscall(long num, long a, long b, long c, long d, long e) { break; case _SYS_GETPROCFS: _sys_getprocfs(a); break; case _SYS_TIME: _sys_time(a); break; case _SYS_GETNULL: _sys_getnull(a); + break; case _SYS_DUPLEX: _sys_duplex(a, b, c); break; case _SYS_EXECBUF: _sys_execbuf((userptr_t)a, b); break; case _SYS_DEBUG_KLOG: _sys_debug_klog((userptr_t)a, b); break; diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 92b904f..3f6fda7 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -166,6 +166,7 @@ vfsback_useraccept(VfsReq *req) res.len = len; res.capacity = req->output.len; res.id = req->id; + res.id2 = req->id2; res.offset = req->offset; res.flags = req->flags; res.op = req->type; diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index 45ec687..d6facfd 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -50,9 +50,7 @@ struct VfsReq { size_t len; } output; - // TODO why doesn't this just have a reference to the handle? - - void __user *id; // handle.file.id + void __user *id, *id2; // handle.file.id long offset; int flags; -- cgit v1.2.3