1 /* Send a signal to a specific pthread. Stub version.
2 Copyright (C) 2014-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <libc-lock.h>
22 #include <shlib-compat.h>
25 __pthread_kill_internal (pthread_t threadid
, int signo
)
27 struct pthread
*pd
= (struct pthread
*) threadid
;
28 if (pd
== THREAD_SELF
)
30 /* Use the actual TID from the kernel, so that it refers to the
31 current thread even if called after vfork. There is no
32 signal blocking in this case, so that the signal is delivered
33 immediately, before __pthread_kill_internal returns: a signal
34 sent to the thread itself needs to be delivered
35 synchronously. (It is unclear if Linux guarantees the
36 delivery of all pending signals after unblocking in the code
37 below. POSIX only guarantees delivery of a single signal,
38 which may not be the right one.) */
39 pid_t tid
= INTERNAL_SYSCALL_CALL (gettid
);
40 int ret
= INTERNAL_SYSCALL_CALL (kill
, tid
, signo
);
41 return INTERNAL_SYSCALL_ERROR_P (ret
) ? INTERNAL_SYSCALL_ERRNO (ret
) : 0;
44 /* Block all signals, as required by pd->exit_lock. */
46 __libc_signal_block_all (&old_mask
);
47 __libc_lock_lock (pd
->exit_lock
);
51 /* The thread is about to exit (or has exited). Sending the
52 signal is either not observable (the target thread has already
53 blocked signals at this point), or it will fail, or it might be
54 delivered to a new, unrelated thread that has reused the TID.
55 So do not actually send the signal. Do not report an error
56 because the threadid argument is still valid (the thread ID
57 lifetime has not ended), and ESRCH (for example) would be
62 /* Using tgkill is a safety measure. pd->exit_lock ensures that
63 the target thread cannot exit. */
64 ret
= INTERNAL_SYSCALL_CALL (tgkill
, __getpid (), pd
->tid
, signo
);
65 ret
= INTERNAL_SYSCALL_ERROR_P (ret
) ? INTERNAL_SYSCALL_ERRNO (ret
) : 0;
68 __libc_lock_unlock (pd
->exit_lock
);
69 __libc_signal_restore_set (&old_mask
);
75 __pthread_kill (pthread_t threadid
, int signo
)
77 /* Disallow sending the signal we use for cancellation, timers,
78 for the setxid implementation. */
79 if (__is_internal_signal (signo
))
82 return __pthread_kill_internal (threadid
, signo
);
84 /* Some architectures (for instance arm) might pull raise through libgcc, so
85 avoid the symbol version if it ends up being used on ld.so. */
87 libc_hidden_def (__pthread_kill
)
88 versioned_symbol (libc
, __pthread_kill
, pthread_kill
, GLIBC_2_34
);
90 # if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34)
91 compat_symbol (libc
, __pthread_kill
, pthread_kill
, GLIBC_2_0
);