summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2023-09-25 00:12:57 +0200
committerdzwdz2023-09-25 00:12:57 +0200
commit2c78dc983d09e136dd016ae6ecee6b191e033de1 (patch)
treefa3f0c858a0c1b61d00d4a7474e80b1aa0368bbf /src/kernel
parent16138fc20fc9c472af37fb8385a997a0d9202f32 (diff)
kernel/intr: accept a message, allow killing processes via intrs
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/proc.c9
-rw-r--r--src/kernel/proc.h2
-rw-r--r--src/kernel/syscalls.c16
-rw-r--r--src/kernel/vfs/procfs.c4
4 files changed, 25 insertions, 6 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 0ce0f50..dc17af2 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -382,7 +382,14 @@ void proc_tryintr(Proc *p) {
}
}
-void proc_intr(Proc *p) {
+void proc_intr(Proc *p, const char *buf, size_t len) {
+ assert(buf != NULL || len == 0);
+
+ if (4 <= len && memcmp(buf, "kill", 4) == 0) {
+ proc_kill(p, EINTR);
+ return;
+ }
+
if (!p->intr_fn) return;
proc_tryintr(p);
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index d437b8c..2261f85 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -123,7 +123,7 @@ void proc_tryreap(Proc *dead);
void proc_tryintr(Proc *p);
/** Send an interupt to a process. */
-void proc_intr(Proc *proc);
+void proc_intr(Proc *p, const char *buf, size_t len);
/** Switches execution to any running process. */
_Noreturn void proc_switch_any(void);
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 8ff5112..edc74bb 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -356,10 +356,20 @@ void _sys_filicide(void) {
}
}
-void _sys_intr(void) {
+int _sys_intr(const char __user *msg, size_t len) {
+ char buf[INTR_MAX];
+ int count = 0;
+ if (INTR_MAX < len) {
+ SYSCALL_RETURN(-EINVAL);
+ }
+ if (pcpy_from(proc_cur, buf, msg, len) < len) {
+ SYSCALL_RETURN(-EFAULT);
+ }
for (Proc *p = proc_cur->child; p; p = proc_next(p, proc_cur)) {
- proc_intr(p);
+ proc_intr(p, buf, len);
+ count++;
}
+ SYSCALL_RETURN(count);
}
void _sys_intr_set(void __user *ip) {
@@ -481,7 +491,7 @@ long _syscall(long num, long a, long b, long c, long d, long e) {
break; case _SYS_PIPE: _sys_pipe((userptr_t)a, b);
break; case _SYS_SLEEP: _sys_sleep(a);
break; case _SYS_FILICIDE: _sys_filicide();
- break; case _SYS_INTR: _sys_intr();
+ break; case _SYS_INTR: _sys_intr((userptr_t)a, b);
break; case _SYS_INTR_SET: _sys_intr_set((userptr_t)a);
break; case _SYS_GETPID: _sys_getpid();
break; case _SYS_GETPPID: _sys_getppid();
diff --git a/src/kernel/vfs/procfs.c b/src/kernel/vfs/procfs.c
index 7ba43d8..5031840 100644
--- a/src/kernel/vfs/procfs.c
+++ b/src/kernel/vfs/procfs.c
@@ -146,7 +146,9 @@ procfs_accept(VfsReq *req)
);
vfsreq_finish_short(req, res);
} else if (req->type == VFSOP_WRITE && h->type == PhIntr) {
- proc_intr(p);
+ size_t len = min(sizeof buf, req->input.len);
+ len = pcpy_from(req->caller, buf, req->input.buf, len);
+ proc_intr(p, buf, len);
vfsreq_finish_short(req, req->input.len);
} else {
vfsreq_finish_short(req, -ENOSYS);