diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 66ce697200..cb83f00380 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -194,6 +194,7 @@ namespace Kernel BAN::ErrorOr sys_pthread_exit(void* value); BAN::ErrorOr sys_pthread_join(pthread_t thread, void** value); BAN::ErrorOr sys_pthread_self(); + BAN::ErrorOr sys_pthread_kill(pthread_t thread, int signal); BAN::ErrorOr sys_tcgetpgrp(int fd); BAN::ErrorOr sys_tcsetpgrp(int fd, pid_t pgid); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 1c2d5a48a7..1c281fdff2 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -2557,6 +2557,25 @@ namespace Kernel return Thread::current().tid(); } + BAN::ErrorOr Process::sys_pthread_kill(pthread_t tid, int signal) + { + if (signal != 0 && (signal < _SIGMIN || signal > _SIGMAX)) + return BAN::Error::from_errno(EINVAL); + + LockGuard _(m_process_lock); + + for (auto* thread : m_threads) + { + if (thread->tid() != tid) + continue; + if (signal != 0) + thread->add_signal(signal); + return 0; + } + + return BAN::Error::from_errno(ESRCH); + } + BAN::ErrorOr Process::sys_tcgetpgrp(int fd) { LockGuard _(m_process_lock); diff --git a/userspace/libraries/LibC/include/sys/syscall.h b/userspace/libraries/LibC/include/sys/syscall.h index 9721653268..c8cf2e93ba 100644 --- a/userspace/libraries/LibC/include/sys/syscall.h +++ b/userspace/libraries/LibC/include/sys/syscall.h @@ -103,6 +103,7 @@ __BEGIN_DECLS O(SYS_PTHREAD_EXIT, pthread_exit) \ O(SYS_PTHREAD_JOIN, pthread_join) \ O(SYS_PTHREAD_SELF, pthread_self) \ + O(SYS_PTHREAD_KILL, pthread_kill) \ O(SYS_EPOLL_CREATE1, epoll_create1) \ O(SYS_EPOLL_CTL, epoll_ctl) \ O(SYS_EPOLL_PWAIT2, epoll_pwait2) \ diff --git a/userspace/libraries/LibC/signal.cpp b/userspace/libraries/LibC/signal.cpp index e27e2355aa..86ed5685b6 100644 --- a/userspace/libraries/LibC/signal.cpp +++ b/userspace/libraries/LibC/signal.cpp @@ -38,9 +38,18 @@ void psignal(int signum, const char* message) fprintf(stderr, "%s\n", strsignal(signum)); } +int pthread_kill(pthread_t thread, int sig) +{ + if (syscall(SYS_PTHREAD_KILL, thread, sig) == -1) + return errno; + return 0; +} + int pthread_sigmask(int how, const sigset_t* __restrict set, sigset_t* __restrict oset) { - return syscall(SYS_SIGPROCMASK, how, set, oset); + if (syscall(SYS_SIGPROCMASK, how, set, oset) == -1) + return errno; + return 0; } int raise(int sig) @@ -138,7 +147,12 @@ int sigpending(sigset_t* set) int sigprocmask(int how, const sigset_t* __restrict set, sigset_t* __restrict oset) { - return pthread_sigmask(how, set, oset); + if (int error = pthread_sigmask(how, set, oset)) + { + errno = error; + return -1; + } + return 0; } int sigrelse(int sig)