aboutsummaryrefslogtreecommitdiff
path: root/src/uapi/cap.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-05-24 13:24:27 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-05-24 18:13:43 +0300
commitbc600ecc3bdf0f189861dfb840f70c2339a7a853 (patch)
treed9840b1dc1b865442a028c03ad7109ac67894f6e /src/uapi/cap.c
parent6a7073e5f262db9a4578ff00b5b28e34335564ce (diff)
downloadkmi-bc600ecc3bdf0f189861dfb840f70c2339a7a853.tar.gz
kmi-bc600ecc3bdf0f189861dfb840f70c2339a7a853.zip
rename common to src
+ I keep starting to type src and wondering why autocomplete won't work, I guess src is just uncounciously a better name
Diffstat (limited to 'src/uapi/cap.c')
-rw-r--r--src/uapi/cap.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/uapi/cap.c b/src/uapi/cap.c
new file mode 100644
index 0000000..157ef47
--- /dev/null
+++ b/src/uapi/cap.c
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: copyleft-next-0.3.1 */
+/* Copyright 2023 Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
+
+#include <kmi/uapi.h>
+#include <kmi/caps.h>
+#include <kmi/tcb.h>
+
+/**
+ * @file cap.c
+ * Sycalls handlers for thread capabilities.
+ */
+
+/**
+ * Check that values are legal for thread ID and offset.
+ *
+ * @param tid Thread ID of thread whose caps should be fetched.
+ * @param off Offset of capabilities.
+ * @return Pointer to capabilities of \p tid, \c 0 otherwise.
+ */
+static capflags_t *__get_tcb_caps(id_t tid, size_t off)
+{
+ if (!cap_off_ok(off))
+ return NULL;
+
+ struct tcb *t = get_tcb(tid);
+ if (!t)
+ return NULL;
+
+ return &t->caps;
+}
+
+/**
+ * Set capabilities.
+ *
+ * @param t Current tcb.
+ * @param tid Thread ID whose capabilities to set.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @param caps Mask of capabilities to set.
+ * @return \ref OK on success, \ref ERR_INVAL on invalid input.
+ */
+SYSCALL_DEFINE3(set_cap)(struct tcb *t, sys_arg_t tid, sys_arg_t off,
+ sys_arg_t caps)
+{
+ if (!is_set(t->caps, CAP_CAPS))
+ return_args1(t, ERR_PERM);
+
+ capflags_t *c;
+ if (!(c = __get_tcb_caps(tid, off)))
+ return_args1(t, ERR_INVAL);
+
+ set_caps(*c, off, caps);
+ return_args1(t, OK);
+}
+
+/**
+ * Get capabilities.
+ *
+ * @param t Current tcb.
+ * @param tid Thread ID whose capabilities to get.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @return \ref OK, capabilities.
+ */
+SYSCALL_DEFINE2(get_cap)(struct tcb *t, sys_arg_t tid, sys_arg_t off)
+{
+ capflags_t *c;
+ if (!(c = __get_tcb_caps(tid, off)))
+ return_args1(t, ERR_INVAL);
+
+ return_args2(t, OK, get_caps(*c, off));
+}
+
+/**
+ * Clear capabilities.
+ *
+ * @param t Current tcb.
+ * @param tid Thread ID whose capabilities to clear.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @param caps Mask of capabilities to clear.
+ * @return ERR_LERM if invalid permissions, ERR_INVAL if \p tid doesn't exist,
+ * otherwise OK.
+ */
+SYSCALL_DEFINE3(clear_cap)(struct tcb *t, sys_arg_t tid, sys_arg_t off,
+ sys_arg_t caps)
+{
+ if (!is_set(t->caps, CAP_CAPS))
+ return_args1(t, ERR_PERM);
+
+ capflags_t *c;
+ if (!(c = __get_tcb_caps(tid, off)))
+ return_args1(t, ERR_INVAL);
+
+ clear_caps(*c, off, caps);
+ return_args1(t, OK);
+}