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 /*
6 *
7 * Copyright (c) International Business Machines Corp., 2002
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /*kill2.c */
25 /*======================================================================
26 >KEYS: < kill(), wait(), signal()
27 >WHAT: < Check that when a child is killed by its parent, it returns the
28 < correct values to the waiting parent--the child sets signal to
29 < ignore the kill
30 >HOW: < For each signal: Send that signal to a child that has elected
31 < to catch the signal, check that the correct status was returned
32 < to the waiting parent.
33 < NOTE: Signal 9 (kill) is not catchable, and must be dealt with
34 < separately.
35 >BUGS: < None known
36 ======================================================================*/
37 #ifndef _GNU_SOURCE
38 #define _GNU_SOURCE 1
39 #endif
40
41 #include <stdio.h>
42 #include <sys/types.h>
43 #include <signal.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <sys/wait.h>
47 #include <errno.h>
48
49 //char progname[] = "kill2()";
50 /***** LTP Port *****/
51 #include "test.h"
52 #define ITER 3
53 #define FAILED 0
54 #define PASSED 1
55
56 char *TCID = "kill12";
57
58 int local_flag = PASSED;
59 int block_number;
60 FILE *temp;
61 int TST_TOTAL = 1;
62 static int sig;
63
64 int anyfail();
65 int blenter();
66 int instress();
67 void setup();
68 void terror();
69 void fail_exit();
70 void ok_exit();
71 int forkfail();
72 void do_child();
73
74 /***** ** ** *****/
75
76 int chflag;
77
78 /*--------------------------------------------------------------------*/
main(int argc,char ** argv)79 int main(int argc, char **argv)
80 {
81 /***** BEGINNING OF MAIN. *****/
82 int pid, npid;
83 int nsig, exno, nexno, status;
84 int ret_val = 0;
85 int core;
86 void chsig();
87
88 #ifdef UCLINUX
89
90 tst_parse_opts(argc, argv, NULL, NULL);
91
92 maybe_run_child(&do_child, "dd", &temp, &sig);
93 #endif
94
95 setup();
96 //tempdir(); /* move to new directory */ 12/20/2003
97 blenter();
98
99 exno = 1;
100
101 if (sigset(SIGCLD, chsig) == SIG_ERR) {
102 fprintf(temp, "\tsigset failed, errno = %d\n", errno);
103 fail_exit();
104 }
105
106 for (sig = 1; sig < 14; sig++) {
107 fflush(temp);
108 chflag = 0;
109
110 pid = FORK_OR_VFORK();
111 if (pid < 0) {
112 forkfail();
113 }
114
115 if (pid == 0) {
116 #ifdef UCLINUX
117 if (self_exec(argv[0], "dd", temp, sig) < 0) {
118 tst_brkm(TBROK, NULL, "self_exec FAILED - "
119 "terminating test.");
120 }
121 #else
122 do_child();
123 #endif
124 } else {
125 //fprintf(temp, "Testing signal %d\n", sig);
126
127 while (!chflag) /* wait for child */
128 sleep(1);
129
130 kill(pid, sig); /* child should ignroe this sig */
131 kill(pid, SIGCLD); /* child should exit */
132
133 #ifdef BCS
134 while ((npid = wait(&status)) != pid
135 || (npid == -1 && errno == EINTR)) ;
136 if (npid != pid) {
137 fprintf(temp,
138 "wait error: wait returned wrong pid\n");
139 ret_val = 1;
140 }
141 #else
142 while ((npid = waitpid(pid, &status, 0)) != -1
143 || errno == EINTR) ;
144 #endif
145
146 /*
147 nsig = status & 0177;
148 core = status & 0200;
149 nexno = (status & 0xff00) >> 8;
150 */
151 /***** LTP Port *****/
152 nsig = WTERMSIG(status);
153 #ifdef WCOREDUMP
154 core = WCOREDUMP(status);
155 #endif
156 nexno = WIFEXITED(status);
157 /***** ** ** *****/
158
159 /* nsig is the signal number returned by wait
160 it should be 0, except when sig = 9 */
161
162 if ((sig == 9) && (nsig != sig)) {
163 fprintf(temp, "wait error: unexpected signal"
164 " returned when the signal sent was 9"
165 " The status of the process is %d \n",
166 status);
167 ret_val = 1;
168 }
169 if ((sig != 9) && (nsig != 0)) {
170 fprintf(temp, "wait error: unexpected signal "
171 "returned, the status of the process is "
172 "%d \n", status);
173 ret_val = 1;
174 }
175
176 /* nexno is the exit number returned by wait
177 it should be 1, except when sig = 9 */
178
179 if (sig == 9)
180 if (nexno != 0) {
181 fprintf(temp, "signal error: unexpected"
182 " exit number returned when"
183 " signal sent was 9, the status"
184 " of the process is %d \n",
185 status);
186 ret_val = 1;
187 } else;
188 else if (nexno != 1) {
189 fprintf(temp, "signal error: unexpected exit "
190 "number returned,the status of the"
191 " process is %d\n", status);
192 ret_val = 1;
193 }
194 }
195 }
196 if (ret_val)
197 local_flag = FAILED;
198
199 /*--------------------------------------------------------------------*/
200 anyfail();
201 tst_exit();
202 } /******** END OF MAIN. ********/
203
204 /*--------------------------------------------------------------------*/
205
chsig(void)206 void chsig(void)
207 {
208 chflag++;
209 }
210
211 /****** LTP Port *****/
anyfail(void)212 int anyfail(void)
213 {
214 (local_flag == FAILED) ? tst_resm(TFAIL,
215 "Test failed") : tst_resm(TPASS,
216 "Test passed");
217 tst_exit();
218 }
219
do_child(void)220 void do_child(void)
221 {
222 int exno = 1;
223
224 #ifdef UCLINUX
225 if (sigset(SIGCLD, chsig) == SIG_ERR) {
226 fprintf(temp, "\tsigset failed, errno = %d\n", errno);
227 fail_exit();
228 }
229 #endif
230
231 sigset(sig, SIG_IGN); /* set to ignore signal */
232 kill(getppid(), SIGCLD); /* tell parent we are ready */
233 while (!chflag)
234 sleep(1); /* wait for parent */
235
236 exit(exno);
237 }
238
setup(void)239 void setup(void)
240 {
241 temp = stderr;
242 }
243
blenter(void)244 int blenter(void)
245 {
246 //tst_resm(TINFO, "Enter block %d", block_number);
247 local_flag = PASSED;
248 return 0;
249 }
250
terror(char * message)251 void terror(char *message)
252 {
253 tst_resm(TBROK, "Reason: %s:%s", message, strerror(errno));
254 }
255
fail_exit(void)256 void fail_exit(void)
257 {
258 local_flag = FAILED;
259 anyfail();
260
261 }
262
forkfail(void)263 int forkfail(void)
264 {
265 tst_brkm(TBROK, NULL, "FORK FAILED - terminating test.");
266 }
267
268 /****** ** ** *******/
269