1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
4 * Authors: Bob Clark, Barrie Kletscher
5 * Copyright (C) 2015 Cyril Hrubis <[email protected]>
6 * Copyright (C) 2021 SUSE LLC Andrea Cervesato <[email protected]>
7 */
8
9 /*\
10 * [Description]
11 *
12 * This test checks following conditions:
13 *
14 * 1. sighold action to turn off the receipt of all signals was done without error.
15 * 2. After signals were held, and sent, no signals were trapped.
16 */
17
18 #define _XOPEN_SOURCE 600
19 #include <signal.h>
20 #include "tst_test.h"
21
22 #ifndef NSIG
23 # define NSIG _NSIG
24 #endif
25
26 #ifndef NUMSIGS
27 # define NUMSIGS NSIG
28 #endif
29
30 static int sigs_catched;
31 static int sigs_map[NUMSIGS];
32
skip_sig(int sig)33 static int skip_sig(int sig)
34 {
35 if (sig >= 32 && sig < SIGRTMIN)
36 return 1;
37
38 switch (sig) {
39 case SIGCHLD:
40 case SIGKILL:
41 case SIGALRM:
42 case SIGSTOP:
43 return 1;
44 default:
45 return 0;
46 }
47 }
48
handle_sigs(int sig)49 static void handle_sigs(int sig)
50 {
51 sigs_map[sig] = 1;
52 sigs_catched++;
53 }
54
do_child(void)55 static void do_child(void)
56 {
57 int sig;
58
59 for (sig = 1; sig < NUMSIGS; sig++) {
60 if (skip_sig(sig))
61 continue;
62
63 SAFE_SIGNAL(sig, handle_sigs);
64 }
65
66 for (sig = 1; sig < NUMSIGS; sig++) {
67 if (skip_sig(sig))
68 continue;
69
70 if (sighold(sig))
71 tst_brk(TBROK | TERRNO, "sighold(%s %i)", tst_strsig(sig), sig);
72 }
73
74 TST_CHECKPOINT_WAKE_AND_WAIT(0);
75
76 if (!sigs_catched) {
77 tst_res(TPASS, "all signals were hold");
78 return;
79 }
80
81 tst_res(TFAIL, "signal handler was executed");
82
83 for (sig = 1; sig < NUMSIGS; sig++)
84 if (sigs_map[sig])
85 tst_res(TINFO, "Signal %i(%s) catched", sig, tst_strsig(sig));
86 }
87
run(void)88 static void run(void)
89 {
90 pid_t pid_child;
91 int signal;
92
93 pid_child = SAFE_FORK();
94 if (!pid_child) {
95 do_child();
96 return;
97 }
98
99 TST_CHECKPOINT_WAIT(0);
100
101 for (signal = 1; signal < NUMSIGS; signal++) {
102 if (skip_sig(signal))
103 continue;
104
105 SAFE_KILL(pid_child, signal);
106 }
107
108 TST_CHECKPOINT_WAKE(0);
109 }
110
111 static struct tst_test test = {
112 .test_all = run,
113 .forks_child = 1,
114 .needs_checkpoints = 1,
115 };
116