]> git.corax.cc Git - corax/commitdiff
Make a thread execute the signal handler itself if it is delivering a signal to the...
authorMatthias Kruk <m@m10k.eu>
Thu, 2 Jan 2020 07:39:45 +0000 (16:39 +0900)
committerMatthias Kruk <m@m10k.eu>
Thu, 2 Jan 2020 07:39:45 +0000 (16:39 +0900)
kernel/core/process.c

index 7d45a27f96fc2f2d91e3904b088c926ec0492059..23335e2ce0fc6a785153489a4a45b1fd698f2d7f 100644 (file)
@@ -9,6 +9,7 @@
 #include <signal.h>
 #include <string.h>
 #include <spinlock.h>
+#include <unistd.h>
 #include "fd.h"
 #include "sched.h"
 
@@ -496,6 +497,7 @@ int process_memcpy_ktop(process_t *proc, void *dst, void *src, u32_t bytes)
 {
        int ret_val;
 
+       dbg_printf("pg_dir_memcpy(%p, %p, NULL, %p, 0x%08x)\n", proc, dst, src, bytes);
        ret_val = pg_dir_memcpy(proc->p_pgdir, dst, NULL, src, bytes);
 
        return(ret_val);
@@ -734,25 +736,33 @@ int process_signal_deliver(process_t *proc, int signal)
        ret_val = -EINVAL;
 
        if(proc && signal > 0 && signal <= SIGUNUSED) {
+               process_t *cproc;
                stack_frame_t *kstk;
                u32_t *vesp3;
                u32_t *pesp3;
                task_t *task;
                int i;
 
-               /* FIXME: Need to suspend the process in order to deliver the signal safely */
-               process_suspend(proc);
+               cproc = process_get_current();
 
-               /*
-                * Elect a task to handle the signal - right now, this is simple since the
-                * implementation doesn't support more than one task per process, and we
-                * can just pick the first (and only) one.
-                */
-               for(task = NULL, i = 0; i < CONFIG_PROC_MAXTASKS; i++) {
-                       if(proc->p_tasks[i]) {
-                               task = proc->p_tasks[i];
-                               break;
+               if(cproc != proc) {
+                       /* FIXME: Need to suspend the process in order to deliver the signal safely */
+                       process_suspend(proc);
+
+                       /*
+                        * Elect a task to handle the signal - right now, this is simple since the
+                        * implementation doesn't support more than one task per process, and we
+                        * can just pick the first (and only) one.
+                        */
+                       for(task = NULL, i = 0; i < CONFIG_PROC_MAXTASKS; i++) {
+                               if(proc->p_tasks[i]) {
+                                       task = proc->p_tasks[i];
+                                       break;
+                               }
                        }
+               } else {
+                       /* handle the signal in the current task */
+                       task = task_get_current();
                }
 
                if(!task) {
@@ -838,14 +848,16 @@ cleanup:
        return(ret_val);
 }
 
+/*
+ * FIXME: Don't call kernel code from _sig_* functions
+ *
+ * The _sig_* functions will be executed in user-mode after the
+ * process has returned from kernel-mode via iret. Kernel-mode
+ * code will have to be called through the usual syscall interface.
+ */
 static void _sig_term(int sig)
 {
-       process_t *cproc;
-
-       cproc = process_get_current();
-
-       /* FIXME: terminate the process */
-
+       _exit(sig);
        return;
 }
 
@@ -857,21 +869,12 @@ static void _sig_ign(int sig)
 
 static void _sig_core(int sig)
 {
-       process_t *cproc;
-
-       cproc = process_get_current();
-
-       /* FIXME: terminate process and generate a core dump */
-
+       _exit(sig);
        return;
 }
 
 static void _sig_stop(int sig)
 {
-       process_t *cproc;
-
-       cproc = process_get_current();
-
        /*
         * FIXME: Stop the process
         *  - Change the process state
@@ -881,16 +884,11 @@ static void _sig_stop(int sig)
         *
         * Or better yet, make it wait on a lock in the stop handler.
         */
-
        return;
 }
 
 static void _sig_cont(int sig)
 {
-       process_t *cproc;
-
-       cproc = process_get_current();
-
        /*
         * FIXME: Continue the process
         *  - Change its state back to a runnable state