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 #include "test.h"
50 #define ITER 3
51 #define FAILED 0
52 #define PASSED 1
53
54 char *TCID = "kill12";
55
56 int local_flag = PASSED;
57 int block_number;
58 FILE *temp;
59 int TST_TOTAL = 1;
60 static int sig;
61
62 int anyfail();
63 int blenter();
64 int instress();
65 void setup();
66 void terror();
67 void fail_exit();
68 void ok_exit();
69 int forkfail();
70 void do_child();
71
72 int chflag;
73
main(int argc,char ** argv)74 int main(int argc, char **argv)
75 {
76 int pid, npid;
77 int nsig, exno, nexno, status;
78 int ret_val = 0;
79 int core;
80 void chsig();
81
82 tst_parse_opts(argc, argv, NULL, NULL);
83
84 setup();
85 blenter();
86
87 exno = 1;
88
89 if (sigset(SIGCHLD, chsig) == SIG_ERR) {
90 fprintf(temp, "\tsigset failed, errno = %d\n", errno);
91 fail_exit();
92 }
93
94 for (sig = 1; sig < 14; sig++) {
95 fflush(temp);
96 chflag = 0;
97
98 pid = FORK_OR_VFORK();
99 if (pid < 0) {
100 forkfail();
101 }
102
103 if (pid == 0) {
104 do_child();
105 } else {
106 //fprintf(temp, "Testing signal %d\n", sig);
107
108 while (!chflag) /* wait for child */
109 sleep(1);
110
111 kill(pid, sig); /* child should ignroe this sig */
112 kill(pid, SIGCHLD); /* child should exit */
113
114 #ifdef BCS
115 while ((npid = wait(&status)) != pid
116 || (npid == -1 && errno == EINTR)) ;
117 if (npid != pid) {
118 fprintf(temp,
119 "wait error: wait returned wrong pid\n");
120 ret_val = 1;
121 }
122 #else
123 while ((npid = waitpid(pid, &status, 0)) != -1
124 || errno == EINTR) ;
125 #endif
126
127 /*
128 nsig = status & 0177;
129 core = status & 0200;
130 nexno = (status & 0xff00) >> 8;
131 */
132 /***** LTP Port *****/
133 nsig = WTERMSIG(status);
134 #ifdef WCOREDUMP
135 core = WCOREDUMP(status);
136 #endif
137 nexno = WIFEXITED(status);
138 /***** ** ** *****/
139
140 /* nsig is the signal number returned by wait
141 it should be 0, except when sig = 9 */
142
143 if ((sig == 9) && (nsig != sig)) {
144 fprintf(temp, "wait error: unexpected signal"
145 " returned when the signal sent was 9"
146 " The status of the process is %d \n",
147 status);
148 ret_val = 1;
149 }
150 if ((sig != 9) && (nsig != 0)) {
151 fprintf(temp, "wait error: unexpected signal "
152 "returned, the status of the process is "
153 "%d \n", status);
154 ret_val = 1;
155 }
156
157 /* nexno is the exit number returned by wait
158 it should be 1, except when sig = 9 */
159
160 if (sig == 9)
161 if (nexno != 0) {
162 fprintf(temp, "signal error: unexpected"
163 " exit number returned when"
164 " signal sent was 9, the status"
165 " of the process is %d \n",
166 status);
167 ret_val = 1;
168 } else;
169 else if (nexno != 1) {
170 fprintf(temp, "signal error: unexpected exit "
171 "number returned,the status of the"
172 " process is %d\n", status);
173 ret_val = 1;
174 }
175 }
176 }
177 if (ret_val)
178 local_flag = FAILED;
179
180 anyfail();
181 tst_exit();
182 }
183
chsig(void)184 void chsig(void)
185 {
186 chflag++;
187 }
188
anyfail(void)189 int anyfail(void)
190 {
191 (local_flag == FAILED) ? tst_resm(TFAIL,
192 "Test failed") : tst_resm(TPASS,
193 "Test passed");
194 tst_exit();
195 }
196
do_child(void)197 void do_child(void)
198 {
199 int exno = 1;
200
201 sigset(sig, SIG_IGN); /* set to ignore signal */
202 kill(getppid(), SIGCHLD); /* tell parent we are ready */
203 while (!chflag)
204 sleep(1); /* wait for parent */
205
206 exit(exno);
207 }
208
setup(void)209 void setup(void)
210 {
211 temp = stderr;
212 }
213
blenter(void)214 int blenter(void)
215 {
216 //tst_resm(TINFO, "Enter block %d", block_number);
217 local_flag = PASSED;
218 return 0;
219 }
220
terror(char * message)221 void terror(char *message)
222 {
223 tst_resm(TBROK, "Reason: %s:%s", message, strerror(errno));
224 }
225
fail_exit(void)226 void fail_exit(void)
227 {
228 local_flag = FAILED;
229 anyfail();
230
231 }
232
forkfail(void)233 int forkfail(void)
234 {
235 tst_brkm(TBROK, NULL, "FORK FAILED - terminating test.");
236 }
237