فهرست منبع

feat(kill): add syscall kill()

greatbridf 2 سال پیش
والد
کامیت
cf416c45b5

+ 1 - 0
gblibc/CMakeLists.txt

@@ -18,6 +18,7 @@ add_library(gblibc STATIC
     src/alloca.c
     src/stat.c
     src/time.c
+    src/signal.c
 )
 
 add_library(crt0 OBJECT

+ 5 - 0
gblibc/include/signal.h

@@ -1,6 +1,8 @@
 #ifndef __GBLIBC_SIGNAL_H_
 #define __GBLIBC_SIGNAL_H_
 
+#include <sys/types.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -10,6 +12,9 @@ extern "C" {
 #define SIGPIPE 13
 #define SIGSTOP 19
 
+int kill(pid_t pid, int sig);
+int raise(int sig);
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 0
gblibc/private-include/syscall.h

@@ -20,6 +20,7 @@
 #define SYS_execve (59)
 #define SYS_exit (60)
 #define SYS_wait (61)
+#define SYS_kill (62)
 #define SYS_getdents (78)
 #define SYS_getcwd (79)
 #define SYS_chdir (80)

+ 23 - 0
gblibc/src/signal.c

@@ -0,0 +1,23 @@
+#include <syscall.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+
+int kill(pid_t pid, int sig)
+{
+    int ret = syscall2(SYS_kill, pid, sig);
+    if (ret < 0) {
+        errno = -ret;
+        return -1;
+    }
+    return ret;
+}
+
+int raise(int sig)
+{
+    pid_t pid = getpid();
+    if (pid < 0)
+        return -1;
+
+    return kill(pid, sig);
+}

+ 1 - 1
include/kernel/process.hpp

@@ -489,7 +489,7 @@ public:
     void send_signal(pid_t pid, kernel::sig_t signal)
     {
         auto iter = this->find(pid);
-        if (!iter)
+        if (iter)
             return iter->signals.set(signal);
     }
     void send_signal_grp(pid_t pgid, kernel::sig_t signal)

+ 18 - 4
include/kernel/signal.hpp

@@ -8,10 +8,10 @@ namespace kernel {
 
 using sig_t = uint32_t;
 
-constexpr sig_t SIGINT = 1 << 0;
-constexpr sig_t SIGQUIT = 1 << 1;
-constexpr sig_t SIGSTOP = 1 << 2;
-constexpr sig_t SIGPIPE = 1 << 3;
+constexpr sig_t SIGINT = 2;
+constexpr sig_t SIGQUIT = 3;
+constexpr sig_t SIGSTOP = 13;
+constexpr sig_t SIGPIPE = 19;
 
 class signal_list {
 public:
@@ -21,6 +21,20 @@ private:
     list_type m_list;
     sig_t m_mask;
 
+public:
+    static constexpr bool check_valid(sig_t sig)
+    {
+        switch (sig) {
+        case SIGINT:
+        case SIGQUIT:
+        case SIGSTOP:
+        case SIGPIPE:
+            return true;
+        default:
+            return false;
+        }
+    }
+
 public:
     constexpr signal_list(void)
         : m_mask(0)

+ 5 - 2
src/kernel/process.cpp

@@ -458,10 +458,13 @@ void check_signal()
     switch (current_process->signals.pop()) {
     case kernel::SIGINT:
     case kernel::SIGQUIT:
-    case kernel::SIGSTOP:
-        procs->get_ctrl_tty(current_process->pid)->clear_read_buf();
+    case kernel::SIGSTOP: {
+        tty* ctrl_tty = procs->get_ctrl_tty(current_process->pid);
+        if (ctrl_tty)
+            ctrl_tty->clear_read_buf();
         kill_current(-1);
         break;
+    }
     case kernel::SIGPIPE:
         kill_current(-1);
         break;

+ 20 - 0
src/kernel/syscall.cpp

@@ -9,6 +9,7 @@
 #include <kernel/mem.h>
 #include <kernel/mm.hpp>
 #include <kernel/process.hpp>
+#include <kernel/signal.hpp>
 #include <kernel/syscall.hpp>
 #include <kernel/tty.hpp>
 #include <kernel/vfs.hpp>
@@ -541,6 +542,24 @@ int _syscall_umask(interrupt_stack* data)
     return old;
 }
 
+int _syscall_kill(interrupt_stack* data)
+{
+    pid_t pid = data->s_regs.edi;
+    int sig = data->s_regs.esi;
+
+    auto* proc = procs->find(pid);
+    if (!proc)
+        return -ESRCH;
+
+    if (!kernel::signal_list::check_valid(sig))
+        return -EINVAL;
+
+    // TODO: check permission
+    procs->send_signal(pid, sig);
+
+    return 0;
+}
+
 extern "C" void syscall_entry(interrupt_stack* data)
 {
     int syscall_no = data->s_regs.eax;
@@ -576,6 +595,7 @@ void init_syscall(void)
     syscall_handlers[59] = _syscall_execve;
     syscall_handlers[60] = _syscall_exit;
     syscall_handlers[61] = _syscall_wait;
+    syscall_handlers[62] = _syscall_kill;
     syscall_handlers[78] = _syscall_getdents;
     syscall_handlers[79] = _syscall_getcwd;
     syscall_handlers[80] = _syscall_chdir;