• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3  *  AUTHOR           :  Dave Baumgartner
4  *                   :  Rewrote 12/92 by Richard Logan
5  *  CO-PILOT         :  Barrie Kletscher
6  *  DATE STARTED     :  10/17/85
7  * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of version 2 of the GNU General Public License as
11  * published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it would be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * Further, this software is distributed without any warranty that it is
18  * free of the rightful claim of any third person regarding infringement
19  * or the like.  Any license provided herein, whether implied or
20  * otherwise, applies only to this software file.  Patent licenses, if
21  * any, provided herein do not apply to combinations of this program with
22  * other software, or any other product whatsoever.
23  *
24  * You should have received a copy of the GNU General Public License along
25  * with this program; if not, write the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27  *
28  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
29  * Mountain View, CA  94043, or:
30  *
31  * http://www.sgi.com
32  *
33  * For further information regarding this notice, see:
34  *
35  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
36  *
37  */
38 /*
39  * TEST ITEMS
40  *
41  *	1. SIGKILL can not be set to be caught, errno:EINVAL (POSIX).
42  *	2. SIGKILL can not be caught.
43  *	3. SIGKILL can not be set to be ignored, errno:EINVAL (POSIX).
44  *	4. SIGKILL can not be ignored.
45  *	5. SIGKILL can not be reset to default, errno:EINVAL (POSIX).
46  */
47 #include <signal.h>
48 #include <errno.h>
49 #include <unistd.h>
50 #include <fcntl.h>
51 #include <string.h>
52 #include <stdlib.h>
53 #include <sys/wait.h>
54 
55 #include "test.h"
56 #include "safe_macros.h"
57 
58 static void setup(void);
59 static void do_test(int tc);
60 static void do_child(void);
61 static void catchsig(int sig);
62 
63 static struct tcase {
64 	void (*sighandler)(int);
65 	int kill;
66 } tcases[] = {
67 	{SIG_IGN, 0},
68 	{SIG_DFL, 0},
69 	{catchsig, 0},
70 	{SIG_IGN, 1},
71 	{SIG_DFL, 1},
72 	{catchsig, 1},
73 };
74 
75 char *TCID = "signal01";
76 int TST_TOTAL = ARRAY_SIZE(tcases);
77 
78 static int tcase;
79 
main(int argc,char * argv[])80 int main(int argc, char *argv[])
81 {
82 	int lc, i;
83 
84 	tst_parse_opts(argc, argv, NULL, NULL);
85 
86 #ifdef UCLINUX
87 	maybe_run_child(&do_child, "d", &tcase);
88 #endif
89 
90 	setup();
91 
92 	for (lc = 0; TEST_LOOPING(lc); lc++) {
93 		for (i = 0; i < TST_TOTAL; i++)
94 			do_test(i);
95 	}
96 
97 	tst_exit();
98 }
99 
do_test(int tc)100 static void do_test(int tc)
101 {
102 	pid_t pid;
103 	int res;
104 	pid = FORK_OR_VFORK();
105 
106 	switch (pid) {
107 	case 0:
108 #ifdef UCLINUX
109 		if (self_exec(argv0, "d", tc) < 0)
110 			tst_brkm(TBROK | TERRNO, NULL, "self_exec() failed");
111 #else
112 		tcase = tc;
113 		do_child();
114 #endif
115 	break;
116 	case -1:
117 		tst_resm(TBROK | TERRNO, "fork() failed");
118 	break;
119 	default:
120 		if (tcases[tc].kill) {
121 			TST_PROCESS_STATE_WAIT(NULL, pid, 'S');
122 
123 			SAFE_KILL(NULL, pid, SIGKILL);
124 
125 			SAFE_WAITPID(NULL, pid, &res, 0);
126 
127 			if (WIFSIGNALED(res)) {
128 				if (WTERMSIG(res) == SIGKILL) {
129 					tst_resm(TPASS, "Child killed with SIGKILL");
130 				} else {
131 					tst_resm(TFAIL, "Child killed with %s",
132 					         tst_strsig(WTERMSIG(res)));
133 				}
134 			} else {
135 				tst_resm(TFAIL, "Child not killed by signal");
136 			}
137 		} else {
138 			tst_record_childstatus(NULL, pid);
139 		}
140 	break;
141 	}
142 }
143 
catchsig(int sig)144 static void catchsig(int sig)
145 {
146 	(void)sig;
147 }
148 
strhandler(void * sighandler)149 static const char *strhandler(void *sighandler)
150 {
151 	switch ((long)sighandler) {
152 	case (long)SIG_DFL:
153 		return "SIG_DFL";
154 	case (long)SIG_IGN:
155 		return "SIG_IGN";
156 	default:
157 		return "catchsig()";
158 	}
159 }
160 
do_child(void)161 static void do_child(void)
162 {
163 	void *ret;
164 	void (*sighandler)(int) = tcases[tcase].sighandler;
165 
166 	ret = signal(SIGKILL, sighandler);
167 
168 	if (tcases[tcase].kill)
169 		pause();
170 
171 	if (ret == SIG_ERR || errno == EINVAL) {
172 		tst_resm(TPASS, "signal(SIGKILL, %p(%s)) failed with EINVAL",
173 		         sighandler, strhandler(sighandler));
174 	} else {
175 		if (ret != SIG_ERR) {
176 			tst_resm(TFAIL, "signal(SIGKILL, %p(%s)) didn't fail",
177 			         sighandler, strhandler(sighandler));
178 		} else {
179 			tst_resm(TFAIL | TERRNO,
180 			         "signal(SIGKILL, %p(%s)) should fail with EINVAL",
181 			          sighandler, strhandler(sighandler));
182 		}
183 	}
184 
185 	tst_exit();
186 }
187 
setup(void)188 static void setup(void)
189 {
190 	tst_sig(FORK, DEF_HANDLER, NULL);
191 
192 	TEST_PAUSE;
193 }
194