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