1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * kill07.c
23 *
24 * DESCRIPTION
25 * Test case to check that SIGKILL can not be caught.
26 *
27 * ALGORITHM
28 * call setup
29 * setup some shared memory
30 * loop if the -i option was given
31 * set up to catch SIGKILL
32 * if SIGKILL is caught set the shared memory flag.
33 * fork a child
34 * execute the kill system call
35 * check the return value
36 * if return value is -1
37 * issue a FAIL message, break remaining tests and cleanup
38 * if we are doing functional testing
39 * if the process was terminated with the expected signal and the
40 * signal was not caught.
41 * issue a PASS message
42 * otherwise
43 * issue a FAIL message
44 * call cleanup
45 *
46 * USAGE
47 * kill07 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
48 * where, -c n : Run n copies concurrently.
49 * -f : Turn off functionality Testing.
50 * -i n : Execute test n times.
51 * -I x : Execute test for x seconds.
52 * -P x : Pause for x seconds between iterations.
53 * -t : Turn on syscall timing.
54 *
55 * HISTORY
56 * 07/2001 Ported by Wayne Boyer
57 *
58 * RESTRICTIONS
59 * This test should be run as a non-root user.
60 */
61
62 #include "test.h"
63
64 #include <signal.h>
65 #include <errno.h>
66 #include <sys/ipc.h>
67 #include <sys/shm.h>
68 #include <sys/wait.h>
69
70 void cleanup(void);
71 void setup(void);
72 void sighandler(int sig);
73 void do_child(void);
74
75 char *TCID = "kill07";
76 int TST_TOTAL = 1;
77 int shmid1;
78 extern key_t semkey;
79 int *flag;
80
81 extern int getipckey();
82 extern void rm_shm(int);
83
84 #define TEST_SIG SIGKILL
85
main(int ac,char ** av)86 int main(int ac, char **av)
87 {
88 int lc;
89 pid_t pid;
90 int exno, status, nsig, asig, ret;
91 struct sigaction my_act, old_act;
92
93 tst_parse_opts(ac, av, NULL, NULL);
94
95 setup(); /* global setup */
96
97 /* The following loop checks looping state if -i option given */
98 for (lc = 0; TEST_LOOPING(lc); lc++) {
99
100 /* reset tst_count in case we are looping */
101 tst_count = 0;
102 status = 1;
103 exno = 1;
104 my_act.sa_handler = sighandler;
105 my_act.sa_flags = SA_RESTART;
106 sigemptyset(&my_act.sa_mask);
107
108 if ((shmid1 = shmget(semkey, (int)getpagesize(),
109 0666 | IPC_CREAT)) == -1) {
110 tst_brkm(TBROK, cleanup,
111 "Failed to setup shared memory");
112 }
113
114 if (*(flag = shmat(shmid1, 0, 0)) == -1) {
115 tst_brkm(TBROK, cleanup,
116 "Failed to attatch shared memory:%d", *flag);
117 }
118
119 *flag = 0;
120
121 /* setup the signal handler */
122 ret = sigaction(TEST_SIG, &my_act, &old_act);
123
124 pid = tst_fork();
125 if (pid < 0) {
126 tst_brkm(TBROK, cleanup, "Fork of child failed");
127 } else if (pid == 0) {
128 do_child();
129 } else {
130 /* sighandler should not catch this signal */
131 /* if it does flag will be set to 1 */
132 sleep(1);
133 TEST(kill(pid, TEST_SIG));
134 waitpid(pid, &status, 0);
135 }
136
137 if (TEST_RETURN == -1) {
138 tst_brkm(TFAIL, cleanup, "%s failed - errno = %d : %s",
139 TCID, TEST_ERRNO, strerror(TEST_ERRNO));
140 }
141
142 /*
143 * Check to see if the process was terminated with the
144 * expected signal.
145 */
146 nsig = WTERMSIG(status);
147 asig = WIFSIGNALED(status);
148 if ((asig == 0) & (*flag == 1)) {
149 tst_resm(TFAIL, "SIGKILL was unexpectedly"
150 " caught");
151 } else if ((asig == 1) & (nsig == TEST_SIG)) {
152 tst_resm(TINFO, "received expected signal %d",
153 nsig);
154 tst_resm(TPASS,
155 "Did not catch signal as expected");
156 } else if (nsig) {
157 tst_resm(TFAIL,
158 "expected signal %d received %d",
159 TEST_SIG, nsig);
160 } else {
161 tst_resm(TFAIL, "No signals received");
162 }
163
164 if (shmdt(flag)) {
165 tst_brkm(TBROK, cleanup, "shmdt failed ");
166 }
167 }
168
169 cleanup();
170 tst_exit();
171 }
172
173 /*
174 * sighandler() - try to catch SIGKILL
175 */
176
sighandler(int sig)177 void sighandler(int sig)
178 {
179 /* do nothing */
180 *flag = 1;
181 return;
182 }
183
184 /*
185 * do_child()
186 */
do_child(void)187 void do_child(void)
188 {
189 int exno = 1;
190
191 sleep(300);
192 tst_resm(TINFO, "Child never received a signal");
193 exit(exno);
194 }
195
196 /*
197 * setup() - performs all ONE TIME setup for this test
198 */
setup(void)199 void setup(void)
200 {
201
202 TEST_PAUSE;
203
204 /*
205 * Create a temporary directory and cd into it.
206 * This helps to ensure that a unique msgkey is created.
207 * See libs/libltpipc/libipc.c for more information.
208 */
209 tst_tmpdir();
210
211 /* get an IPC resource key */
212 semkey = getipckey();
213
214 }
215
216 /*
217 * cleanup() - performs all the ONE TIME cleanup for this test at completion
218 * or premature exit.
219 */
cleanup(void)220 void cleanup(void)
221 {
222
223 /*
224 * remove the shared memory
225 */
226 rm_shm(shmid1);
227
228 tst_rmdir();
229
230 }
231