diff --git a/libc/thread/pthread_kill.c b/libc/thread/pthread_kill.c index 127c27748..6c1722965 100644 --- a/libc/thread/pthread_kill.c +++ b/libc/thread/pthread_kill.c @@ -24,6 +24,7 @@ #include "libc/intrin/atomic.h" #include "libc/intrin/describeflags.h" #include "libc/intrin/strace.h" +#include "libc/runtime/internal.h" #include "libc/runtime/syslib.internal.h" #include "libc/sysv/consts/sicode.h" #include "libc/thread/posixthread.internal.h" @@ -46,8 +47,12 @@ errno_t pthread_kill(pthread_t thread, int sig) { if (pt) _pthread_ref(pt); if (!thread) { + // avoid crashing on easily predictable npe + // chances are you need a barrier to synchronize startup err = EFAULT; } else if (!(1 <= sig && sig <= 64)) { + // cosmo only supports this many signals + // some platforms have more but we're not sure what they do err = EINVAL; } else if (thread == __get_tls()->tib_pthread) { err = raise(sig); // XNU will EDEADLK it otherwise @@ -60,8 +65,15 @@ errno_t pthread_kill(pthread_t thread, int sig) { if (IsXnuSilicon()) { err = __syslib->__pthread_kill(_pthread_syshand(pt), sig); } else { + int r = 0; int e = errno; - if (sys_tkill(_pthread_tid(pt), sig, pt->tib)) { + int tid = _pthread_tid(pt); + if (IsLinux() || IsFreebsd()) { + r = sys_tgkill(__pid, tid, sig); + } else { + r = sys_tkill(tid, sig, pt->tib); + } + if (r) { err = errno; errno = e; }