summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2024-07-20 23:17:36 +0200
committerdzwdz2024-07-20 23:17:36 +0200
commit1fc2d9c88af77c3af81b6bd461e6b019b97d2dbb (patch)
tree56d19935958983882872495f556bdb74c8ae26b8 /src/kernel
parente88aee660ea668cc96d8a5a11060b6e02b2f0fd7 (diff)
*: moving files
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/handle.h1
-rw-r--r--src/kernel/syscalls.c32
-rw-r--r--src/kernel/vfs/request.c1
-rw-r--r--src/kernel/vfs/request.h4
4 files changed, 35 insertions, 3 deletions
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;