1 /* Smoke test for the tgkill system call.
2 Copyright (C) 2019-2024 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/>. */
21 #include <support/check.h>
22 #include <support/namespace.h>
23 #include <support/xthread.h>
26 /* Number of times sigusr1_handler has been invoked. */
27 static volatile sig_atomic_t signals_delivered
;
29 /* Expected TID of the thread receiving the signal. */
30 static pid_t expected_signal_tid
;
33 sigusr1_handler (int signo
)
35 TEST_COMPARE (expected_signal_tid
, gettid ());
45 /* Send signals from the subprocess which are not expected to be
46 delivered. There is no handler for SIGUSR2, so delivery will
47 result in a test failure. CLOSURE must point to a valid PID/TID
48 combination that is still running. */
50 subprocess_no_tid_match (void *closure
)
52 struct pid_and_tid
*ids
= closure
;
53 TEST_COMPARE (tgkill (ids
->pid
, gettid (), SIGUSR2
), -1);
54 TEST_COMPARE (errno
, ESRCH
);
56 TEST_COMPARE (tgkill (getpid (), ids
->tid
, SIGUSR2
), -1);
57 TEST_COMPARE (errno
, ESRCH
);
59 TEST_COMPARE (tgkill (getppid (), gettid (), SIGUSR2
), -1);
60 TEST_COMPARE (errno
, ESRCH
);
63 /* Called from threadfunc below. */
65 subprocess (void *closure
)
67 int original_tid
= expected_signal_tid
;
69 /* Do not expect that the following signals are delivered to the
70 subprocess. The parent process retains the original
71 expected_signal_tid value. */
72 expected_signal_tid
= 0;
73 TEST_COMPARE (tgkill (getpid (), original_tid
, SIGUSR1
), -1);
74 TEST_COMPARE (errno
, ESRCH
);
75 TEST_COMPARE (tgkill (getppid (), gettid (), SIGUSR1
), -1);
76 TEST_COMPARE (errno
, ESRCH
);
77 TEST_COMPARE (expected_signal_tid
, 0);
79 /* This call has the correct PID/TID combination and is therefore
80 expected to succeed. */
81 TEST_COMPARE (tgkill (getppid (), original_tid
, SIGUSR1
), 0);
85 threadfunc (void *closure
)
87 TEST_VERIFY (gettid () != getpid ());
88 expected_signal_tid
= gettid ();
89 TEST_COMPARE (tgkill (getpid (), gettid (), SIGUSR1
), 0);
90 TEST_COMPARE (signals_delivered
, 1);
91 signals_delivered
= 0;
93 support_isolate_in_subprocess (subprocess
, NULL
);
95 /* Check that exactly one signal arrived from the subprocess. */
96 TEST_COMPARE (signals_delivered
, 1);
98 support_isolate_in_subprocess (subprocess_no_tid_match
,
105 support_isolate_in_subprocess (subprocess_no_tid_match
,
106 &(struct pid_and_tid
)
118 TEST_VERIFY_EXIT (signal (SIGUSR1
, sigusr1_handler
) != SIG_ERR
);
120 expected_signal_tid
= gettid ();
121 TEST_COMPARE (gettid (), getpid ());
122 TEST_COMPARE (tgkill (getpid (), gettid (), SIGUSR1
), 0);
123 TEST_COMPARE (signals_delivered
, 1);
124 signals_delivered
= 0;
126 xpthread_join (xpthread_create (NULL
, threadfunc
, NULL
));
128 TEST_VERIFY (signal (SIGUSR1
, SIG_DFL
) == sigusr1_handler
);
132 #include <support/test-driver.c>