• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* IBM Corporation
2  * 01/02/2003	Port to LTP	avenkat@us.ibm.com
3  * 06/30/2001	Port to Linux	nsharoff@us.ibm.com
4  *
5  *   Copyright (c) International Business Machines  Corp., 2002
6  *   Copyright (c) Cyril Hrubis <chrubis@suse.cz> 2014
7  *
8  *   This program is free software;  you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16  *   the GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program;  if not, write to the Free Software
20  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /*
24 
25   Test check that when a child is killed by its parent, it returns the correct
26   values to the waiting parent--default behaviour assumed by child.
27 
28  */
29 
30 #define _GNU_SOURCE 1
31 
32 #include <stdio.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <signal.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <sys/wait.h>
39 #include <sys/resource.h>
40 
41 #include "test.h"
42 #include "safe_macros.h"
43 
44 #define FAILED 0
45 #define PASSED 1
46 
47 char *TCID = "kill11";
48 
49 int local_flag = PASSED;
50 int block_number;
51 FILE *temp;
52 int TST_TOTAL = 1;
53 static int sig;
54 
55 void setup(void);
56 void do_child(void);
57 
58 /*
59  * These signals terminate process by default, some create core file.
60  */
61 struct tcase {
62 	int sig;
63 	int dumps_core;
64 } tcases[] = {
65 	{SIGHUP, 0},
66 	{SIGINT, 0},
67 	{SIGQUIT, 1},
68 	{SIGILL, 1},
69 	{SIGTRAP, 1},
70 	{SIGABRT, 1},
71 	{SIGIOT, 1},
72 	{SIGBUS, 1},
73 	{SIGFPE, 1},
74 	{SIGKILL, 0},
75 	{SIGUSR1, 0},
76 	{SIGSEGV, 1},
77 	{SIGUSR2, 0},
78 	{SIGPIPE, 0},
79 	{SIGALRM, 0},
80 	{SIGTERM, 0},
81 	{SIGXCPU, 1},
82 	{SIGXFSZ, 1},
83 	{SIGVTALRM, 0},
84 	{SIGPROF, 0},
85 	{SIGIO, 0},
86 	{SIGPWR, 0},
87 	{SIGSYS, 1},
88 };
89 
verify_kill(struct tcase * t)90 static void verify_kill(struct tcase *t)
91 {
92 	int core;
93 	int pid, npid;
94 	int nsig, nexno, status;
95 
96 	if (t->sig != SIGKILL) {
97 #ifndef BCS
98 		if (t->sig != SIGSTOP)
99 #endif
100 			if (sigset(t->sig, SIG_DFL) == SIG_ERR) {
101 				tst_brkm(TBROK | TERRNO, tst_rmdir,
102 				         "sigset(%d) failed", sig);
103 			}
104 	}
105 
106 	pid = FORK_OR_VFORK();
107 	if (pid < 0)
108 		tst_brkm(TBROK | TERRNO, tst_rmdir, "fork() failed");
109 
110 	if (pid == 0) {
111 #ifdef UCLINUX
112 		if (self_exec(argv[0], "dd", t->sig) < 0)
113 			exit(1);
114 #else
115 		do_child();
116 #endif
117 	}
118 
119 	kill(pid, t->sig);
120 	npid = wait(&status);
121 
122 	if (npid != pid) {
123 		tst_resm(TFAIL, "wait() returned %d, expected %d", npid, pid);
124 		return;
125 	}
126 
127 	nsig = WTERMSIG(status);
128 #ifdef WCOREDUMP
129 	core = WCOREDUMP(status);
130 #endif
131 	nexno = WIFEXITED(status);
132 
133 	if (t->dumps_core) {
134 		if (!core) {
135 			tst_resm(TFAIL, "core dump bit not set for %s", tst_strsig(t->sig));
136 			return;
137 		}
138 	} else {
139 		if (core) {
140 			tst_resm(TFAIL, "core dump bit set for %s", tst_strsig(t->sig));
141 			return;
142 		}
143 	}
144 
145 	if (nsig != t->sig) {
146 		tst_resm(TFAIL, "wait: unexpected signal %d returned, expected %d", nsig, t->sig);
147 		return;
148 	}
149 
150 	if (nexno != 0) {
151 		tst_resm(TFAIL,
152 			"signal: unexpected exit number %d returned, expected 0\n",
153 			nexno);
154 		return;
155 	}
156 
157 	tst_resm(TPASS, "signal %-16s%s", tst_strsig(t->sig),
158 	         t->dumps_core ? " dumped core" : "");
159 }
160 
main(int argc,char ** argv)161 int main(int argc, char **argv)
162 {
163 	int lc;
164 	unsigned int i;
165 
166 	tst_parse_opts(argc, argv, NULL, NULL);
167 
168 #ifdef UCLINUX
169 	maybe_run_child(&do_child, "dd", &sig);
170 #endif
171 
172 	setup();
173 
174 	for (lc = 0; TEST_LOOPING(lc); lc++) {
175 		for (i = 0; i < ARRAY_SIZE(tcases); i++)
176 			verify_kill(tcases + i);
177 	}
178 
179 	tst_rmdir();
180 	tst_exit();
181 }
182 
do_child(void)183 void do_child(void)
184 {
185 	int i;
186 
187 	for (i = 0; i < 180; i++)
188 		sleep(1);
189 
190 	fprintf(stderr, "Child missed siggnal");
191 	fflush(stderr);
192 	exit(1);
193 }
194 
195 /* 1024 GNU blocks */
196 #define MIN_RLIMIT_CORE (1024 * 1024)
197 
setup(void)198 void setup(void)
199 {
200 	struct rlimit rlim;
201 
202 	SAFE_GETRLIMIT(NULL, RLIMIT_CORE, &rlim);
203 
204 	if (rlim.rlim_cur < MIN_RLIMIT_CORE) {
205 		tst_resm(TINFO, "Adjusting RLIMIT_CORE to %i", MIN_RLIMIT_CORE);
206 		rlim.rlim_cur = MIN_RLIMIT_CORE;
207 		SAFE_SETRLIMIT(NULL, RLIMIT_CORE, &rlim);
208 	}
209 
210 	temp = stderr;
211 	tst_tmpdir();
212 }
213