1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Linux Test Project, 2009-2019
4 * Copyright (C) 2009, Ngie Cooper
5 * Copyright (c) 2023 Wei Gao <wegao@suse.com>
6 */
7
8 /*\
9 * [Description]
10 *
11 * This test ptraces itself as per arbitrarily specified signals,
12 * over 0 to SIGRTMAX range.
13 */
14
15 #include <stdlib.h>
16 #include <sys/ptrace.h>
17 #include "lapi/signal.h"
18 #include "tst_test.h"
19
20 static int expect_stop;
21
test_signal(int signum)22 static void test_signal(int signum)
23 {
24 int status;
25 pid_t child;
26
27 child = SAFE_FORK();
28
29 if (!child) {
30 TST_EXP_PASS_SILENT(ptrace(PTRACE_TRACEME, 0, NULL, NULL));
31 tst_res(TDEBUG, "[child] Sending kill(.., %s)", tst_strsig(signum));
32 SAFE_KILL(getpid(), signum);
33 exit(0);
34 }
35
36 SAFE_WAITPID(child, &status, 0);
37
38 switch (signum) {
39 case 0:
40 if (WIFEXITED(status)
41 && WEXITSTATUS(status) == 0) {
42 tst_res(TPASS,
43 "kill(.., 0) exited with 0, as expected.");
44 } else {
45 tst_res(TFAIL,
46 "kill(.., 0) exited with unexpected %s.", tst_strstatus(status));
47 }
48 break;
49 case SIGKILL:
50 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
51 tst_res(TPASS, "Child killed by SIGKILL");
52 else
53 tst_res(TFAIL, "Child %s", tst_strstatus(status));
54 break;
55 /* All other processes should be stopped. */
56 default:
57 if (WIFSTOPPED(status)) {
58 tst_res(TDEBUG, "Stopped as expected");
59 } else {
60 tst_res(TFAIL, "Didn't stop as expected. Child %s", tst_strstatus(status));
61 expect_stop++;
62 }
63 break;
64 }
65
66 if (signum != 0 && signum != SIGKILL)
67 SAFE_PTRACE(PTRACE_CONT, child, NULL, NULL);
68 }
69
run(void)70 static void run(void)
71 {
72 int signum = 0;
73
74 for (signum = 0; signum <= SIGRTMAX; signum++) {
75 if (signum >= __SIGRTMIN && signum < SIGRTMIN)
76 continue;
77 test_signal(signum);
78 }
79 }
80
81 static struct tst_test test = {
82 .test_all = run,
83 .forks_child = 1,
84 };
85