From: Waldemar Kozaczuk <jwkozac...@gmail.com> Committer: Nadav Har'El <n...@scylladb.com> Branch: master
syscalls: minimally implement tgkill The golang applications use the tgkill syscall to implement the raise() function as the issue #1047 describes. The raise() function is then used to propagate SIGTERM signal to the process when Ctrl-C is pressed. For that reason this patch adds very basic implementation of the tgkill syscall. More specifically it only handles the case where tpid specifies current process or -1 and tid specifies the current thread of the caller which in essence is what Golang raise() passes. In this case the tgkill syscall implementation delegates to kill() otherwise it returns failure. This patch also modifies the implementation of the pthread_kill() to make it consistent with the implementation of the tgkill syscall. The pthread_kill is actually called by raise() (see libc/pthread.cc) so just like with tgkill, we check if specified pthread_t is equal to the current thread and in such case we delegate to kill(). Lastly this patch enhances tst-kill.cc to test raise() and pthread_kill(). Refs #1047 Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com> Message-Id: <20210525050253.1141211-2-jwkozac...@gmail.com> --- diff --git a/libc/pthread.cc b/libc/pthread.cc --- a/libc/pthread.cc +++ b/libc/pthread.cc @@ -995,8 +995,19 @@ int pthread_getschedparam(pthread_t thread, int *policy, int pthread_kill(pthread_t thread, int sig) { - WARN_STUBBED(); + // We are assuming that if pthread_kill() is called with thread + // equal to pthread_self(), then most likely it was called by + // raise() (see below) so we simply delegate to kill(). + // This an approximation as it reality multithreaded apps + // may actually send signal to the current thread by directly + // calling pthread_kill() for a reason and then thread specific mask + // would apply, etc. But OSv does not really support sending signals to + // specific threads so we are silently ignoring such case for now. + if (thread == current_pthread) { + return kill(getpid(), sig); + } + WARN_STUBBED(); return EINVAL; } diff --git a/linux.cc b/linux.cc --- a/linux.cc +++ b/linux.cc @@ -371,6 +371,22 @@ static int pselect6(int nfds, fd_set *readfds, fd_set *writefds, return pselect(nfds, readfds, writefds, exceptfds, timeout_ts, NULL); } +static int tgkill(int tgid, int tid, int sig) +{ + // + // Given OSv supports sigle process only, we only support this syscall + // when thread group id is self (getpid()) or -1 (see https://linux.die.net/man/2/tgkill) + // AND tid points to the current thread (caller) + // Ideally we would want to delegate to pthread_kill() but there is no + // easy way to map tgid to pthread_t so we directly delegate to kill(). + if ((tgid == -1 || tgid == getpid()) && (tid == gettid())) { + return kill(tgid, sig); + } + + errno = ENOSYS; + return -1; +} + long syscall(long number, ...) { // Save FPU state and restore it at the end of this function @@ -451,6 +467,7 @@ long syscall(long number, ...) SYSCALL2(mkdir, char*, mode_t); #endif SYSCALL3(mkdirat, int, char*, mode_t); + SYSCALL3(tgkill, int, int, int); } debug_always("syscall(): unimplemented system call %d\n", number); diff --git a/tests/tst-kill.cc b/tests/tst-kill.cc --- a/tests/tst-kill.cc +++ b/tests/tst-kill.cc @@ -13,6 +13,7 @@ #include <stdio.h> #include <unistd.h> #include <errno.h> +#include <pthread.h> int tests = 0, fails = 0; @@ -98,6 +99,10 @@ int main(int ac, char** av) r = kill(17171717, 0); report(r == -1 && errno == ESRCH, "kill of non-existant process"); + report(raise(0) == 0, "raise() should succeed"); + report(pthread_kill(pthread_self(), 0) == 0, "pthread_kill() should succeed with current thread"); + report(pthread_kill((pthread_t)(-1), 0) == EINVAL, "pthread_kill() should fail for thread different than current one"); + // Test alarm(); global = 0; sr = signal(SIGALRM, handler1); -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/000000000000b7fd1505c322fa00%40google.com.