Linux: Add the tgkill function

The tgkill function is sometimes used in crash handlers.

<bits/signal_ext.h> follows the same approach as <bits/unistd_ext.h>
(which was added for the gettid system call wrapper).

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
Florian Weimer 2019-05-14 21:35:09 +02:00
parent 6807f47b81
commit 04b261bdc1
38 changed files with 282 additions and 4 deletions

View File

@ -1,3 +1,49 @@
2019-05-14 Florian Weimer <fweimer@redhat.com>
Linux: Add the tgkill function.
* bits/signal_ext.h: New file.
* manual/signal.texi (Signaling Another Process): Document tgkill.
* signal/Makefile (headers): Add bits/signal_ext.h.
* signal/signal.h: Include <bits/signal_ext.h>.
* sysdeps/unix/sysv/linux/Makefile (tests): Add tst-tgkill.
(tst-tgkill): Link with libpthread.
* sysdeps/unix/sysv/linux/Versions (GLIBC_2.30): Export tgkill.
* sysdeps/unix/sysv/linux/bits/signal_ext.h: New file.
* sysdeps/unix/sysv/linux/bits/tst-tgkill.c: Likewise.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist (GLIBC_2.30): Add
tgkill.
* sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/csky/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist:
Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist:
Likewise.
* sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.
2019-05-14 Carlos O'Donell <carlos@redhat.com>
* manual/search.texi (Tree Search Function): Adjust twalk_r

2
NEWS
View File

@ -20,7 +20,7 @@ Major new features:
twalk function, but it passes an additional caller-supplied argument
to the callback function.
* On Linux, the gettid function has been added.
* On Linux, the gettid and tgkill functions have been added.
* Minguo (Republic of China) calendar support has been added as an
alternative calendar for the following locales: zh_TW, cmn_TW, hak_TW,

21
bits/signal_ext.h Normal file
View File

@ -0,0 +1,21 @@
/* System-specific extensions of <signal.h>, generic version.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _SIGNAL_H
# error "Never include <bits/signal_ext.h> directly; use <signal.h> instead."
#endif

View File

@ -2291,6 +2291,21 @@ The @var{pid} argument does not refer to an existing process or group.
@end table
@end deftypefun
@deftypefun int tgkill (pid_t @var{pid}, pid_t @var{tid}, int @var{signum})
@standards{Linux, signal.h}
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
The @code{tgkill} function sends the signal @var{signum} to the thread
or process with ID @var{tid}, like the @code{kill} function, but only
if the process ID of the thread @var{tid} is equal to @var{pid}. If
the target thread belongs to another process, the function fails with
@code{ESRCH}.
The @code{tgkill} function can be used to avoid sending a signal to a
thread in the wrong process if the caller ensures that the passed
@var{pid} value is not reused by the kernel (for example, if it is the
process ID of the current process, as returned by @code{getpid}).
@end deftypefun
@deftypefun int killpg (int @var{pgid}, int @var{signum})
@standards{BSD, signal.h}
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

View File

@ -31,7 +31,7 @@ headers := signal.h sys/signal.h \
bits/types/sigevent_t.h bits/types/siginfo_t.h \
bits/types/sigset_t.h bits/types/sigval_t.h \
bits/types/stack_t.h bits/types/struct_sigstack.h \
bits/types/__sigval_t.h
bits/types/__sigval_t.h bits/signal_ext.h
routines := signal raise killpg \
sigaction sigprocmask kill \

View File

@ -370,6 +370,9 @@ extern int __libc_current_sigrtmax (void) __THROW;
#define SIGRTMIN (__libc_current_sigrtmin ())
#define SIGRTMAX (__libc_current_sigrtmax ())
/* System-specific extensions. */
#include <bits/signal_ext.h>
__END_DECLS
#endif /* not signal.h */

View File

@ -53,7 +53,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill
tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
tst-tgkill
tests-internal += tst-ofdlocks-compat
# Generate the list of SYS_* macros for the system calls (__NR_*
@ -115,6 +116,7 @@ $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py
$(objpfx)tst-gettid: $(shared-thread-library)
$(objpfx)tst-gettid-kill: $(shared-thread-library)
$(objpfx)tst-tgkill: $(shared-thread-library)
endif # $(subdir) == misc

View File

@ -175,7 +175,7 @@ libc {
getcpu;
}
GLIBC_2.30 {
gettid;
gettid; tgkill;
}
GLIBC_PRIVATE {
# functions used in other libraries

View File

@ -2142,4 +2142,5 @@ GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F

View File

@ -2217,6 +2217,7 @@ GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F

View File

@ -127,6 +127,7 @@ GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0

View File

@ -0,0 +1,31 @@
/* System-specific extensions of <signal.h>, Linux version.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _SIGNAL_H
# error "Never include <bits/signal_ext.h> directly; use <signal.h> instead."
#endif
#ifdef __USE_GNU
/* Send SIGNAL to the thread TID in the thread group (process)
identified by TGID. This function behaves like kill, but also
fails with ESRCH if the specified TID does not belong to the
specified thread group. */
extern int tgkill (__pid_t __tgid, __pid_t __tid, int __signal);
#endif /* __USE_GNU */

View File

@ -2086,4 +2086,5 @@ GLIBC_2.29 xencrypt F
GLIBC_2.29 xprt_register F
GLIBC_2.29 xprt_unregister F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F

View File

@ -2038,6 +2038,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2204,6 +2204,7 @@ GLIBC_2.3.4 vm86 F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2070,6 +2070,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -128,6 +128,7 @@ GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0x98

View File

@ -2147,6 +2147,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2134,4 +2134,5 @@ GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F

View File

@ -2121,6 +2121,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2119,6 +2119,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2127,6 +2127,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2121,6 +2121,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2175,4 +2175,5 @@ GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F

View File

@ -2177,6 +2177,7 @@ GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F

View File

@ -2210,6 +2210,7 @@ GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F

View File

@ -2040,6 +2040,7 @@ GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F

View File

@ -2244,4 +2244,5 @@ GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F

View File

@ -2104,4 +2104,5 @@ GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F

View File

@ -2172,6 +2172,7 @@ GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F

View File

@ -2076,6 +2076,7 @@ GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F

View File

@ -2042,6 +2042,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2166,6 +2166,7 @@ GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F

View File

@ -2093,6 +2093,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -111,3 +111,4 @@ memfd_create EXTRA memfd_create i:si memfd_create
pkey_alloc EXTRA pkey_alloc i:ii pkey_alloc
pkey_free EXTRA pkey_free i:i pkey_free
gettid EXTRA gettid Ei: __gettid gettid
tgkill EXTRA tgkill i:iii __tgkill tgkill

View File

@ -0,0 +1,132 @@
/* Smoke test for the tgkill system call.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <signal.h>
#include <support/check.h>
#include <support/namespace.h>
#include <support/xthread.h>
#include <unistd.h>
/* Number of times sigusr1_handler has been invoked. */
static volatile sig_atomic_t signals_delivered;
/* Expected TID of the thread receiving the signal. */
static pid_t expected_signal_tid;
static void
sigusr1_handler (int signo)
{
TEST_COMPARE (expected_signal_tid, gettid ());
++signals_delivered;
}
struct pid_and_tid
{
pid_t pid;
pid_t tid;
};
/* Send signals from the subprocess which are not expected to be
delivered. There is no handler for SIGUSR2, so delivery will
result in a test failure. CLOSURE must point to a valid PID/TID
combination that is still running. */
static void
subprocess_no_tid_match (void *closure)
{
struct pid_and_tid *ids = closure;
TEST_COMPARE (tgkill (ids->pid, gettid (), SIGUSR2), -1);
TEST_COMPARE (errno, ESRCH);
TEST_COMPARE (tgkill (getpid (), ids->tid, SIGUSR2), -1);
TEST_COMPARE (errno, ESRCH);
TEST_COMPARE (tgkill (getppid (), gettid (), SIGUSR2), -1);
TEST_COMPARE (errno, ESRCH);
}
/* Called from threadfunc below. */
static void
subprocess (void *closure)
{
int original_tid = expected_signal_tid;
/* Do not expect that the folloing signals are delivered to the
subprocess. The parent process retains the original
expected_signal_tid value. */
expected_signal_tid = 0;
TEST_COMPARE (tgkill (getpid (), original_tid, SIGUSR1), -1);
TEST_COMPARE (errno, ESRCH);
TEST_COMPARE (tgkill (getppid (), gettid (), SIGUSR1), -1);
TEST_COMPARE (errno, ESRCH);
TEST_COMPARE (expected_signal_tid, 0);
/* This call has the correct PID/TID combination and is therefore
expected to suceed. */
TEST_COMPARE (tgkill (getppid (), original_tid, SIGUSR1), 0);
}
static void *
threadfunc (void *closure)
{
TEST_VERIFY (gettid () != getpid ());
expected_signal_tid = gettid ();
TEST_COMPARE (tgkill (getpid (), gettid (), SIGUSR1), 0);
TEST_COMPARE (signals_delivered, 1);
signals_delivered = 0;
support_isolate_in_subprocess (subprocess, NULL);
/* Check that exactly one signal arrived from the subprocess. */
TEST_COMPARE (signals_delivered, 1);
support_isolate_in_subprocess (subprocess_no_tid_match,
&(struct pid_and_tid)
{
.pid = getpid (),
.tid = gettid (),
});
support_isolate_in_subprocess (subprocess_no_tid_match,
&(struct pid_and_tid)
{
.pid = getpid (),
.tid = getpid (),
});
return NULL;
}
static int
do_test (void)
{
TEST_VERIFY_EXIT (signal (SIGUSR1, sigusr1_handler) != SIG_ERR);
expected_signal_tid = gettid ();
TEST_COMPARE (gettid (), getpid ());
TEST_COMPARE (tgkill (getpid (), gettid (), SIGUSR1), 0);
TEST_COMPARE (signals_delivered, 1);
signals_delivered = 0;
xpthread_join (xpthread_create (NULL, threadfunc, NULL));
TEST_VERIFY (signal (SIGUSR1, SIG_DFL) == sigusr1_handler);
return 0;
}
#include <support/test-driver.c>

View File

@ -2051,6 +2051,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F

View File

@ -2150,4 +2150,5 @@ GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F