xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/sighold/sighold02.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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