xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/kill/kill02.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3*49cdfc7eSAndroid Build Coastguard Worker  *
4*49cdfc7eSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify it
5*49cdfc7eSAndroid Build Coastguard Worker  * under the terms of version 2 of the GNU General Public License as
6*49cdfc7eSAndroid Build Coastguard Worker  * published by the Free Software Foundation.
7*49cdfc7eSAndroid Build Coastguard Worker  *
8*49cdfc7eSAndroid Build Coastguard Worker  * This program is distributed in the hope that it would be useful, but
9*49cdfc7eSAndroid Build Coastguard Worker  * WITHOUT ANY WARRANTY; without even the implied warranty of
10*49cdfc7eSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11*49cdfc7eSAndroid Build Coastguard Worker  *
12*49cdfc7eSAndroid Build Coastguard Worker  * Further, this software is distributed without any warranty that it is
13*49cdfc7eSAndroid Build Coastguard Worker  * free of the rightful claim of any third person regarding infringement
14*49cdfc7eSAndroid Build Coastguard Worker  * or the like.  Any license provided herein, whether implied or
15*49cdfc7eSAndroid Build Coastguard Worker  * otherwise, applies only to this software file.  Patent licenses, if
16*49cdfc7eSAndroid Build Coastguard Worker  * any, provided herein do not apply to combinations of this program with
17*49cdfc7eSAndroid Build Coastguard Worker  * other software, or any other product whatsoever.
18*49cdfc7eSAndroid Build Coastguard Worker  *
19*49cdfc7eSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License along
20*49cdfc7eSAndroid Build Coastguard Worker  * with this program; if not, write the Free Software Foundation, Inc.,
21*49cdfc7eSAndroid Build Coastguard Worker  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22*49cdfc7eSAndroid Build Coastguard Worker  *
23*49cdfc7eSAndroid Build Coastguard Worker  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24*49cdfc7eSAndroid Build Coastguard Worker  * Mountain View, CA  94043, or:
25*49cdfc7eSAndroid Build Coastguard Worker  *
26*49cdfc7eSAndroid Build Coastguard Worker  * http://www.sgi.com
27*49cdfc7eSAndroid Build Coastguard Worker  *
28*49cdfc7eSAndroid Build Coastguard Worker  * For further information regarding this notice, see:
29*49cdfc7eSAndroid Build Coastguard Worker  *
30*49cdfc7eSAndroid Build Coastguard Worker  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31*49cdfc7eSAndroid Build Coastguard Worker  *
32*49cdfc7eSAndroid Build Coastguard Worker  */
33*49cdfc7eSAndroid Build Coastguard Worker /* $Id: kill02.c,v 1.10 2009/08/28 13:20:15 vapier Exp $ */
34*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************************
35*49cdfc7eSAndroid Build Coastguard Worker 
36*49cdfc7eSAndroid Build Coastguard Worker     OS Test -  Silicon Graphics, Inc.
37*49cdfc7eSAndroid Build Coastguard Worker 
38*49cdfc7eSAndroid Build Coastguard Worker     TEST IDENTIFIER :  kill02  Sending a signal to processes with the same process group ID.
39*49cdfc7eSAndroid Build Coastguard Worker 
40*49cdfc7eSAndroid Build Coastguard Worker     PARENT DOCUMENT :  kiltds01  Kill System Call.
41*49cdfc7eSAndroid Build Coastguard Worker 
42*49cdfc7eSAndroid Build Coastguard Worker     AUTHOR          :  Dave Baumgartner
43*49cdfc7eSAndroid Build Coastguard Worker 
44*49cdfc7eSAndroid Build Coastguard Worker     CO-PILOT        :  Barrie Kletscher
45*49cdfc7eSAndroid Build Coastguard Worker 
46*49cdfc7eSAndroid Build Coastguard Worker     DATE STARTED    :  12/30/85
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker     TEST ITEMS
49*49cdfc7eSAndroid Build Coastguard Worker 
50*49cdfc7eSAndroid Build Coastguard Worker 	1. Sending a signal to pid of zero sends to all processes whose process
51*49cdfc7eSAndroid Build Coastguard Worker 	   group ID is equal to the process group ID as the sender.
52*49cdfc7eSAndroid Build Coastguard Worker 
53*49cdfc7eSAndroid Build Coastguard Worker 	2. Sending a signal to pid of zero does not send to processes in another process group.
54*49cdfc7eSAndroid Build Coastguard Worker 
55*49cdfc7eSAndroid Build Coastguard Worker     OUTPUT SPECIFICATIONS
56*49cdfc7eSAndroid Build Coastguard Worker 
57*49cdfc7eSAndroid Build Coastguard Worker 	PASS :
58*49cdfc7eSAndroid Build Coastguard Worker 		kiltcs02 1 PASS The signal was sent to all processes in the process group.
59*49cdfc7eSAndroid Build Coastguard Worker 		kiltcs02 2 PASS The signal was not sent to selective processes that were not in the process group.
60*49cdfc7eSAndroid Build Coastguard Worker 
61*49cdfc7eSAndroid Build Coastguard Worker 	FAIL :
62*49cdfc7eSAndroid Build Coastguard Worker 		kiltcs02 1 FAIL The signal was not sent to all processes in the process group.
63*49cdfc7eSAndroid Build Coastguard Worker 		kiltcs02 2 FAIL The signal was sent to a process that was not in the process group.
64*49cdfc7eSAndroid Build Coastguard Worker 
65*49cdfc7eSAndroid Build Coastguard Worker 	BROK :
66*49cdfc7eSAndroid Build Coastguard Worker 		kiltcs02 # BROK System call XXX failed. Errno:X, Error message:XXX.
67*49cdfc7eSAndroid Build Coastguard Worker 		kiltcs02 # BROK Setting to catch unexpected signal %d failed. Errno: %d, Error message %s.
68*49cdfc7eSAndroid Build Coastguard Worker 		kiltcs02 # BROK Setting to ignore signal %d failed. Errno: %d, Error message %s.
69*49cdfc7eSAndroid Build Coastguard Worker 
70*49cdfc7eSAndroid Build Coastguard Worker 	WARN :
71*49cdfc7eSAndroid Build Coastguard Worker 		kiltcs02 0 WARN Unexpected signal X was caught.
72*49cdfc7eSAndroid Build Coastguard Worker 
73*49cdfc7eSAndroid Build Coastguard Worker     SPECIAL PROCEDURAL REQUIREMENTS
74*49cdfc7eSAndroid Build Coastguard Worker 
75*49cdfc7eSAndroid Build Coastguard Worker 	The program must be linked with tst_res.o.
76*49cdfc7eSAndroid Build Coastguard Worker 
77*49cdfc7eSAndroid Build Coastguard Worker     DETAILED DESCRIPTION
78*49cdfc7eSAndroid Build Coastguard Worker 
79*49cdfc7eSAndroid Build Coastguard Worker 	**Setup**
80*49cdfc7eSAndroid Build Coastguard Worker 	Set up unexpected signal handling.
81*49cdfc7eSAndroid Build Coastguard Worker 	Set up one pipe for each process to be created with no blocking for read.
82*49cdfc7eSAndroid Build Coastguard Worker 
83*49cdfc7eSAndroid Build Coastguard Worker 	**MAIN**
84*49cdfc7eSAndroid Build Coastguard Worker 	If setup fails exit.
85*49cdfc7eSAndroid Build Coastguard Worker 	Fork 2 children(1 & 2).
86*49cdfc7eSAndroid Build Coastguard Worker 	Wait for set up complete messages from the 1st and 2nd child.
87*49cdfc7eSAndroid Build Coastguard Worker 	Send the signal SIGUSR1 with pid equal to zero.
88*49cdfc7eSAndroid Build Coastguard Worker 	Sleep a reasonable amount of time so that each child has been swapped in
89*49cdfc7eSAndroid Build Coastguard Worker 	to process the signal.
90*49cdfc7eSAndroid Build Coastguard Worker 	Now decide the outcome of the test items by reading from each pipe to find
91*49cdfc7eSAndroid Build Coastguard Worker 	out if the child was interrupted by the signal and wrote to it.
92*49cdfc7eSAndroid Build Coastguard Worker 	Remove the second child.
93*49cdfc7eSAndroid Build Coastguard Worker 	Tell the first child it is time to remove it's child B because the decisions have been made.
94*49cdfc7eSAndroid Build Coastguard Worker 	Exit.
95*49cdfc7eSAndroid Build Coastguard Worker 
96*49cdfc7eSAndroid Build Coastguard Worker 	**First Child**
97*49cdfc7eSAndroid Build Coastguard Worker 	Set to catch SIGUSR1 with an int_rout1.
98*49cdfc7eSAndroid Build Coastguard Worker 	Set up to handle the message from the parent to remove child B.
99*49cdfc7eSAndroid Build Coastguard Worker 	Fork two children(A & B).
100*49cdfc7eSAndroid Build Coastguard Worker 	Wait for set up complete messages from child A & child B.
101*49cdfc7eSAndroid Build Coastguard Worker 	Send a set up complete message to the parent.
102*49cdfc7eSAndroid Build Coastguard Worker 	Pause until the signal SIGUSR1 comes in from the parent.
103*49cdfc7eSAndroid Build Coastguard Worker 	Pause until the parent says it is time to remove the child.
104*49cdfc7eSAndroid Build Coastguard Worker 	Exit.
105*49cdfc7eSAndroid Build Coastguard Worker 
106*49cdfc7eSAndroid Build Coastguard Worker 	**Second Child**
107*49cdfc7eSAndroid Build Coastguard Worker 	Set to catch SIGUSR1 with an int_rout2.
108*49cdfc7eSAndroid Build Coastguard Worker 	Set the process group to be something different than the parents.
109*49cdfc7eSAndroid Build Coastguard Worker 	Send a set up complete message to the parent.
110*49cdfc7eSAndroid Build Coastguard Worker 	Pause until killed by parent because this child shouldn't receive signal SIGUSR1.
111*49cdfc7eSAndroid Build Coastguard Worker 
112*49cdfc7eSAndroid Build Coastguard Worker 	**Child A**
113*49cdfc7eSAndroid Build Coastguard Worker 	Set to catch SIGUSR1 with an int_routA.
114*49cdfc7eSAndroid Build Coastguard Worker 	Send a set up complete message to the parent(First Child).
115*49cdfc7eSAndroid Build Coastguard Worker 	Pause until the signal SIGUSR1 comes in from the parent.
116*49cdfc7eSAndroid Build Coastguard Worker 	Exit.
117*49cdfc7eSAndroid Build Coastguard Worker 
118*49cdfc7eSAndroid Build Coastguard Worker 	**Child B**
119*49cdfc7eSAndroid Build Coastguard Worker 	Set to catch SIGUSR1 with an int_routB.
120*49cdfc7eSAndroid Build Coastguard Worker 	Set the process group to be something different than the parents(First Child's).
121*49cdfc7eSAndroid Build Coastguard Worker 	Send a set up complete message to the parent.
122*49cdfc7eSAndroid Build Coastguard Worker 	Pause until killed by parent because this child shouldn't receive signal SIGUSR1.
123*49cdfc7eSAndroid Build Coastguard Worker 
124*49cdfc7eSAndroid Build Coastguard Worker 	**usr1_rout-Used by all children**
125*49cdfc7eSAndroid Build Coastguard Worker 	Write to the appropriate pipe that the signal SIGUSR1 was caught.
126*49cdfc7eSAndroid Build Coastguard Worker 
127*49cdfc7eSAndroid Build Coastguard Worker 	**usr2_rout**
128*49cdfc7eSAndroid Build Coastguard Worker 	Remove child B.
129*49cdfc7eSAndroid Build Coastguard Worker 
130*49cdfc7eSAndroid Build Coastguard Worker ******************************************************************************/
131*49cdfc7eSAndroid Build Coastguard Worker #include <sys/param.h>
132*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
133*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
134*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
135*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
136*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
137*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
138*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
139*49cdfc7eSAndroid Build Coastguard Worker 
140*49cdfc7eSAndroid Build Coastguard Worker #define CHAR_SET_FAILED	"0"	/*Set up failing status transferred through the pipe.   */
141*49cdfc7eSAndroid Build Coastguard Worker #define CHAR_SET_PASSED	"1"	/*Set up passing status transferred through the pipe.   */
142*49cdfc7eSAndroid Build Coastguard Worker #define SIG_CAUGHT	"2"	/*Indicates that the signal SIGUSR1 was caught.         */
143*49cdfc7eSAndroid Build Coastguard Worker #define SIG_RECEIVED	1	/*Integer value that indicates that the signal SIGUSR1  */
144*49cdfc7eSAndroid Build Coastguard Worker 				/*was caught.                                           */
145*49cdfc7eSAndroid Build Coastguard Worker #define SIG_NOT_RECD	0	/*Integer value that indicates that the signal SIGUSR1  */
146*49cdfc7eSAndroid Build Coastguard Worker 				/*was caught.                                           */
147*49cdfc7eSAndroid Build Coastguard Worker #define INT_SET_FAILED	0	/*Set up failing status transferred through the pipe.   */
148*49cdfc7eSAndroid Build Coastguard Worker #define INT_SET_PASSED	1	/*Set up passing status transferred through the pipe.   */
149*49cdfc7eSAndroid Build Coastguard Worker #define SLEEP_TIME	10	/*Amount of time the children get to catch the signal   */
150*49cdfc7eSAndroid Build Coastguard Worker #define TRUE	 	40	/*Child exits with this if execution was as     */
151*49cdfc7eSAndroid Build Coastguard Worker 				/*expected.                                             */
152*49cdfc7eSAndroid Build Coastguard Worker #define FALSE	 	50	/*Child exits with this if it timed out waiting for the         */
153*49cdfc7eSAndroid Build Coastguard Worker 				/*parents signal.                                       */
154*49cdfc7eSAndroid Build Coastguard Worker #define TIMEOUT		60	/*Amount of time given in alarm calls.                  */
155*49cdfc7eSAndroid Build Coastguard Worker #define CHILD_EXIT(VAR) ((VAR >> 8) & 0377)	/*Exit value from the child.               */
156*49cdfc7eSAndroid Build Coastguard Worker #define CHILD_SIG(VAR) (VAR & 0377)	/*Signal value from the termination of child.       */
157*49cdfc7eSAndroid Build Coastguard Worker 				/*from the parent.                                      */
158*49cdfc7eSAndroid Build Coastguard Worker 
159*49cdfc7eSAndroid Build Coastguard Worker int pid1;			/*Return value from 1st fork. Global so that it can be  */
160*49cdfc7eSAndroid Build Coastguard Worker 				/*used in interrupt handling routines.                  */
161*49cdfc7eSAndroid Build Coastguard Worker int pid2;			/*Return value from 2nd fork. Global so that it can be  */
162*49cdfc7eSAndroid Build Coastguard Worker 				/*used in interrupt handling routines.                  */
163*49cdfc7eSAndroid Build Coastguard Worker int pidA;			/*Return value from 1st fork in child 1. Global so that it      */
164*49cdfc7eSAndroid Build Coastguard Worker 				/*can be used in interrupt handling routines.           */
165*49cdfc7eSAndroid Build Coastguard Worker int pidB;			/*Return value from 2nd fork in child 1. Global so that it      */
166*49cdfc7eSAndroid Build Coastguard Worker 				/*can be used in interrupt handling routines.           */
167*49cdfc7eSAndroid Build Coastguard Worker int pipe1_fd[2];		/*Pipe file descriptors used for communication          */
168*49cdfc7eSAndroid Build Coastguard Worker 				/*between child 1 and the 1st parent.                   */
169*49cdfc7eSAndroid Build Coastguard Worker int pipe2_fd[2];		/*Pipe file descriptors used for communication          */
170*49cdfc7eSAndroid Build Coastguard Worker 				/*between child 2 and the 1st parent.                   */
171*49cdfc7eSAndroid Build Coastguard Worker int pipeA_fd[2];		/*Pipe file descriptors used for communication          */
172*49cdfc7eSAndroid Build Coastguard Worker 				/*between child A and the 1st parent.                   */
173*49cdfc7eSAndroid Build Coastguard Worker int pipeB_fd[2];		/*Pipe file descriptors used for communication          */
174*49cdfc7eSAndroid Build Coastguard Worker 				/*between child B and the 1st parent.                   */
175*49cdfc7eSAndroid Build Coastguard Worker char pipe_buf[10];		/*Pipe buffer.                                          */
176*49cdfc7eSAndroid Build Coastguard Worker char buf_tmp1[2], buf_tmp2[2];	/*Temp hold for info read into pipe_buf.                */
177*49cdfc7eSAndroid Build Coastguard Worker int read1_stat = 0;		/*Number of characters read from pipe 1.                */
178*49cdfc7eSAndroid Build Coastguard Worker int read2_stat = 0;		/*Number of characters read from pipe 2.                */
179*49cdfc7eSAndroid Build Coastguard Worker int readA_stat = 0;		/*Number of characters read from pipe A.                */
180*49cdfc7eSAndroid Build Coastguard Worker int readB_stat = 0;		/*Number of characters read from pipe B.                */
181*49cdfc7eSAndroid Build Coastguard Worker int alarm_flag = FALSE;		/*This flag indicates an alarm time out.                        */
182*49cdfc7eSAndroid Build Coastguard Worker char who_am_i = '0';		/*This indicates which process is which when using      */
183*49cdfc7eSAndroid Build Coastguard Worker 				/*interrupt routine usr1_rout.                          */
184*49cdfc7eSAndroid Build Coastguard Worker 
185*49cdfc7eSAndroid Build Coastguard Worker void notify_timeout();		/*Signal handler that the parent enters if it times out */
186*49cdfc7eSAndroid Build Coastguard Worker 				/*waiting for the child to indicate its set up status.  */
187*49cdfc7eSAndroid Build Coastguard Worker void parent_rout();		/*This is the parents routine.                          */
188*49cdfc7eSAndroid Build Coastguard Worker void child1_rout();		/*This is child 1's routine.                            */
189*49cdfc7eSAndroid Build Coastguard Worker void child2_rout();		/*This is child 2's routine.                            */
190*49cdfc7eSAndroid Build Coastguard Worker void childA_rout();		/*This is child A's routine.                            */
191*49cdfc7eSAndroid Build Coastguard Worker void childB_rout();		/*This is child B's routine.                            */
192*49cdfc7eSAndroid Build Coastguard Worker void usr1_rout();		/*This routine is used by all children to indicate that */
193*49cdfc7eSAndroid Build Coastguard Worker 				/*they have caught signal SIGUSR1.                      */
194*49cdfc7eSAndroid Build Coastguard Worker void par_kill();		/*This routine is called by the original parent to      */
195*49cdfc7eSAndroid Build Coastguard Worker 				/*remove child 2 and to indicate to child 1 to          */
196*49cdfc7eSAndroid Build Coastguard Worker 				/*remove its children.                                  */
197*49cdfc7eSAndroid Build Coastguard Worker void chld1_kill();		/*This routine is used by child 1 to remove itself and  */
198*49cdfc7eSAndroid Build Coastguard Worker 				/*its children A and B.                                 */
199*49cdfc7eSAndroid Build Coastguard Worker 
200*49cdfc7eSAndroid Build Coastguard Worker void setup();
201*49cdfc7eSAndroid Build Coastguard Worker void cleanup();
202*49cdfc7eSAndroid Build Coastguard Worker 
203*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "kill02";
204*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 2;
205*49cdfc7eSAndroid Build Coastguard Worker 
main(int ac,char ** av)206*49cdfc7eSAndroid Build Coastguard Worker int main(int ac, char **av)
207*49cdfc7eSAndroid Build Coastguard Worker {
208*49cdfc7eSAndroid Build Coastguard Worker 	int lc;
209*49cdfc7eSAndroid Build Coastguard Worker 
210*49cdfc7eSAndroid Build Coastguard Worker 	tst_parse_opts(ac, av, NULL, NULL);
211*49cdfc7eSAndroid Build Coastguard Worker 
212*49cdfc7eSAndroid Build Coastguard Worker 	setup();
213*49cdfc7eSAndroid Build Coastguard Worker 
214*49cdfc7eSAndroid Build Coastguard Worker 	for (lc = 0; TEST_LOOPING(lc); lc++) {
215*49cdfc7eSAndroid Build Coastguard Worker 
216*49cdfc7eSAndroid Build Coastguard Worker 		tst_count = 0;
217*49cdfc7eSAndroid Build Coastguard Worker 
218*49cdfc7eSAndroid Build Coastguard Worker 		if ((pid1 = tst_fork()) > 0) {
219*49cdfc7eSAndroid Build Coastguard Worker 			if ((pid2 = tst_fork()) > 0) {
220*49cdfc7eSAndroid Build Coastguard Worker 				(void)parent_rout();
221*49cdfc7eSAndroid Build Coastguard Worker 			} else if (pid2 == 0) {
222*49cdfc7eSAndroid Build Coastguard Worker 				(void)child2_rout();
223*49cdfc7eSAndroid Build Coastguard Worker 			} else {
224*49cdfc7eSAndroid Build Coastguard Worker 				/*
225*49cdfc7eSAndroid Build Coastguard Worker 				 *  The second fork failed kill the first child.
226*49cdfc7eSAndroid Build Coastguard Worker 				 */
227*49cdfc7eSAndroid Build Coastguard Worker 				if (kill(pid1, SIGKILL) == -1 && errno != ESRCH) {
228*49cdfc7eSAndroid Build Coastguard Worker 					tst_resm(TWARN,
229*49cdfc7eSAndroid Build Coastguard Worker 						 "Child process may not have been killed.");
230*49cdfc7eSAndroid Build Coastguard Worker 				}
231*49cdfc7eSAndroid Build Coastguard Worker 				tst_brkm(TBROK | TERRNO, cleanup,
232*49cdfc7eSAndroid Build Coastguard Worker 					 "fork failed");
233*49cdfc7eSAndroid Build Coastguard Worker 			}
234*49cdfc7eSAndroid Build Coastguard Worker 
235*49cdfc7eSAndroid Build Coastguard Worker 		} else if (pid1 == 0) {
236*49cdfc7eSAndroid Build Coastguard Worker 			/*
237*49cdfc7eSAndroid Build Coastguard Worker 			 *  This is child 1.
238*49cdfc7eSAndroid Build Coastguard Worker 			 */
239*49cdfc7eSAndroid Build Coastguard Worker 			(void)child1_rout();
240*49cdfc7eSAndroid Build Coastguard Worker 		} else {
241*49cdfc7eSAndroid Build Coastguard Worker 			/*
242*49cdfc7eSAndroid Build Coastguard Worker 			 * Fork failed.
243*49cdfc7eSAndroid Build Coastguard Worker 			 */
244*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
245*49cdfc7eSAndroid Build Coastguard Worker 		}
246*49cdfc7eSAndroid Build Coastguard Worker 	}
247*49cdfc7eSAndroid Build Coastguard Worker 
248*49cdfc7eSAndroid Build Coastguard Worker 	cleanup();
249*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
250*49cdfc7eSAndroid Build Coastguard Worker }				/* END OF MAIN. */
251*49cdfc7eSAndroid Build Coastguard Worker 
252*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************
253*49cdfc7eSAndroid Build Coastguard Worker  *  This is the parents routine.  The parent waits for the children 1 and 2 to
254*49cdfc7eSAndroid Build Coastguard Worker  *  get set up. Then sends the signal and checks the outcome.
255*49cdfc7eSAndroid Build Coastguard Worker  *********************************************************************************/
parent_rout(void)256*49cdfc7eSAndroid Build Coastguard Worker void parent_rout(void)
257*49cdfc7eSAndroid Build Coastguard Worker {
258*49cdfc7eSAndroid Build Coastguard Worker 	/*
259*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set to catch the alarm signal SIGALRM.
260*49cdfc7eSAndroid Build Coastguard Worker 	 */
261*49cdfc7eSAndroid Build Coastguard Worker 	if (signal(SIGALRM, notify_timeout) == SIG_ERR) {
262*49cdfc7eSAndroid Build Coastguard Worker 		(void)par_kill();
263*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL,
264*49cdfc7eSAndroid Build Coastguard Worker 			 "Could not set to catch the parents time out alarm.");
265*49cdfc7eSAndroid Build Coastguard Worker 	}
266*49cdfc7eSAndroid Build Coastguard Worker 
267*49cdfc7eSAndroid Build Coastguard Worker 	/*
268*49cdfc7eSAndroid Build Coastguard Worker 	 *  Setting to catch the timeout alarm worked now let the children start up.
269*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set an alarm which causes a time out on the read pipe loop.
270*49cdfc7eSAndroid Build Coastguard Worker 	 *  The children will notify the parent that set up is complete
271*49cdfc7eSAndroid Build Coastguard Worker 	 *  and the pass/fail status of set up.
272*49cdfc7eSAndroid Build Coastguard Worker 	 */
273*49cdfc7eSAndroid Build Coastguard Worker 	(void)alarm(TIMEOUT);
274*49cdfc7eSAndroid Build Coastguard Worker 
275*49cdfc7eSAndroid Build Coastguard Worker 	while ((read(pipe1_fd[0], pipe_buf, 1) != 1) && (alarm_flag == FALSE))
276*49cdfc7eSAndroid Build Coastguard Worker 		/*EMPTY*/;
277*49cdfc7eSAndroid Build Coastguard Worker 	strncpy(buf_tmp1, pipe_buf, 1);
278*49cdfc7eSAndroid Build Coastguard Worker 	(void)alarm(TIMEOUT);
279*49cdfc7eSAndroid Build Coastguard Worker 
280*49cdfc7eSAndroid Build Coastguard Worker 	while ((read(pipe2_fd[0], pipe_buf, 1) != 1) && (alarm_flag == FALSE))
281*49cdfc7eSAndroid Build Coastguard Worker 		/*EMPTY*/;
282*49cdfc7eSAndroid Build Coastguard Worker 	(void)alarm(0);		/*Reset the alarm clock. */
283*49cdfc7eSAndroid Build Coastguard Worker 	strncpy(buf_tmp2, pipe_buf, 1);
284*49cdfc7eSAndroid Build Coastguard Worker 
285*49cdfc7eSAndroid Build Coastguard Worker 	/*
286*49cdfc7eSAndroid Build Coastguard Worker 	 *  Check the alarm flag.
287*49cdfc7eSAndroid Build Coastguard Worker 	 */
288*49cdfc7eSAndroid Build Coastguard Worker 	if (alarm_flag == TRUE) {
289*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL,
290*49cdfc7eSAndroid Build Coastguard Worker 			 "The set up of the children failed by timing out.");
291*49cdfc7eSAndroid Build Coastguard Worker 		(void)par_kill();
292*49cdfc7eSAndroid Build Coastguard Worker 		cleanup();
293*49cdfc7eSAndroid Build Coastguard Worker 	}
294*49cdfc7eSAndroid Build Coastguard Worker 
295*49cdfc7eSAndroid Build Coastguard Worker 	/*
296*49cdfc7eSAndroid Build Coastguard Worker 	 *  Check to see if either child failed in the set up.
297*49cdfc7eSAndroid Build Coastguard Worker 	 */
298*49cdfc7eSAndroid Build Coastguard Worker 	if ((strncmp(buf_tmp1, CHAR_SET_FAILED, 1) == 0) ||
299*49cdfc7eSAndroid Build Coastguard Worker 	    (strncmp(buf_tmp2, CHAR_SET_FAILED, 1) == 0)) {
300*49cdfc7eSAndroid Build Coastguard Worker 		/*
301*49cdfc7eSAndroid Build Coastguard Worker 		 * Problems were encountered in the set up of one of the children.
302*49cdfc7eSAndroid Build Coastguard Worker 		 * The error message has been displayed by the child.
303*49cdfc7eSAndroid Build Coastguard Worker 		 */
304*49cdfc7eSAndroid Build Coastguard Worker 		(void)par_kill();
305*49cdfc7eSAndroid Build Coastguard Worker 		cleanup();
306*49cdfc7eSAndroid Build Coastguard Worker 	}
307*49cdfc7eSAndroid Build Coastguard Worker 
308*49cdfc7eSAndroid Build Coastguard Worker 	/*
309*49cdfc7eSAndroid Build Coastguard Worker 	 *  Setup passed, now send SIGUSR1 to process id of zero.
310*49cdfc7eSAndroid Build Coastguard Worker 	 */
311*49cdfc7eSAndroid Build Coastguard Worker 	TEST(kill(0, SIGUSR1));
312*49cdfc7eSAndroid Build Coastguard Worker 
313*49cdfc7eSAndroid Build Coastguard Worker 	if (TEST_RETURN == -1) {
314*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TTERRNO, NULL, "kill() failed");
315*49cdfc7eSAndroid Build Coastguard Worker 		(void)par_kill();
316*49cdfc7eSAndroid Build Coastguard Worker 		cleanup();
317*49cdfc7eSAndroid Build Coastguard Worker 	}
318*49cdfc7eSAndroid Build Coastguard Worker 
319*49cdfc7eSAndroid Build Coastguard Worker 	/*
320*49cdfc7eSAndroid Build Coastguard Worker 	 *  Sleep for a while to allow the children to get a chance to
321*49cdfc7eSAndroid Build Coastguard Worker 	 *  catch the signal.
322*49cdfc7eSAndroid Build Coastguard Worker 	 */
323*49cdfc7eSAndroid Build Coastguard Worker 	(void)sleep(SLEEP_TIME);
324*49cdfc7eSAndroid Build Coastguard Worker 
325*49cdfc7eSAndroid Build Coastguard Worker 	/*
326*49cdfc7eSAndroid Build Coastguard Worker 	 *  The signal was sent above and time has run out for child response,
327*49cdfc7eSAndroid Build Coastguard Worker 	 *  check the outcomes.
328*49cdfc7eSAndroid Build Coastguard Worker 	 */
329*49cdfc7eSAndroid Build Coastguard Worker 	read1_stat = read(pipe1_fd[0], pipe_buf, 1);
330*49cdfc7eSAndroid Build Coastguard Worker 	if (read1_stat == -1 && errno == EAGAIN)
331*49cdfc7eSAndroid Build Coastguard Worker 		read1_stat = 0;
332*49cdfc7eSAndroid Build Coastguard Worker 	read2_stat = read(pipe2_fd[0], pipe_buf, 1);
333*49cdfc7eSAndroid Build Coastguard Worker 	if (read2_stat == -1 && errno == EAGAIN)
334*49cdfc7eSAndroid Build Coastguard Worker 		read2_stat = 0;
335*49cdfc7eSAndroid Build Coastguard Worker 	readA_stat = read(pipeA_fd[0], pipe_buf, 1);
336*49cdfc7eSAndroid Build Coastguard Worker 	if (readA_stat == -1 && errno == EAGAIN)
337*49cdfc7eSAndroid Build Coastguard Worker 		readA_stat = 0;
338*49cdfc7eSAndroid Build Coastguard Worker 	readB_stat = read(pipeB_fd[0], pipe_buf, 1);
339*49cdfc7eSAndroid Build Coastguard Worker 	if (readB_stat == -1 && errno == EAGAIN)
340*49cdfc7eSAndroid Build Coastguard Worker 		readB_stat = 0;
341*49cdfc7eSAndroid Build Coastguard Worker 
342*49cdfc7eSAndroid Build Coastguard Worker 	if (read1_stat == -1 || read2_stat == -1 ||
343*49cdfc7eSAndroid Build Coastguard Worker 	    readA_stat == -1 || readB_stat == -1) {
344*49cdfc7eSAndroid Build Coastguard Worker 		/*
345*49cdfc7eSAndroid Build Coastguard Worker 		 * The read system call failed.
346*49cdfc7eSAndroid Build Coastguard Worker 		 */
347*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "read() failed");
348*49cdfc7eSAndroid Build Coastguard Worker 		(void)par_kill();
349*49cdfc7eSAndroid Build Coastguard Worker 		cleanup();
350*49cdfc7eSAndroid Build Coastguard Worker 	}
351*49cdfc7eSAndroid Build Coastguard Worker 
352*49cdfc7eSAndroid Build Coastguard Worker 	/*
353*49cdfc7eSAndroid Build Coastguard Worker 	 * Check the processes that were supposed to get the signal.
354*49cdfc7eSAndroid Build Coastguard Worker 	 */
355*49cdfc7eSAndroid Build Coastguard Worker 	if (read1_stat == SIG_RECEIVED) {
356*49cdfc7eSAndroid Build Coastguard Worker 		if (readA_stat == SIG_RECEIVED) {
357*49cdfc7eSAndroid Build Coastguard Worker 			/*
358*49cdfc7eSAndroid Build Coastguard Worker 			 *  Both processes, 1 and A, that were supposed to receive
359*49cdfc7eSAndroid Build Coastguard Worker 			 *  the signal did receive the signal.
360*49cdfc7eSAndroid Build Coastguard Worker 			 */
361*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TPASS,
362*49cdfc7eSAndroid Build Coastguard Worker 				 "The signal was sent to all processes in the process group.");
363*49cdfc7eSAndroid Build Coastguard Worker 		} else {	/*Process A didn't receive the signal. */
364*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL,
365*49cdfc7eSAndroid Build Coastguard Worker 				 "Process A did not receive the signal.");
366*49cdfc7eSAndroid Build Coastguard Worker 		}
367*49cdfc7eSAndroid Build Coastguard Worker 
368*49cdfc7eSAndroid Build Coastguard Worker 	} else {		/*Process 1 didn't receive the signal. */
369*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TFAIL, "Process 1 did not receive the signal.");
370*49cdfc7eSAndroid Build Coastguard Worker 	}
371*49cdfc7eSAndroid Build Coastguard Worker 
372*49cdfc7eSAndroid Build Coastguard Worker 	/*
373*49cdfc7eSAndroid Build Coastguard Worker 	 * Check the processes that were not supposed to get the signal.
374*49cdfc7eSAndroid Build Coastguard Worker 	 */
375*49cdfc7eSAndroid Build Coastguard Worker 	if (read2_stat == SIG_NOT_RECD) {
376*49cdfc7eSAndroid Build Coastguard Worker 		if (readB_stat == SIG_NOT_RECD) {
377*49cdfc7eSAndroid Build Coastguard Worker 			/*
378*49cdfc7eSAndroid Build Coastguard Worker 			 *  Both processes, 2 and B did not receive the signal.
379*49cdfc7eSAndroid Build Coastguard Worker 			 */
380*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TPASS,
381*49cdfc7eSAndroid Build Coastguard Worker 				 "The signal was not sent to selective processes that were not in the process group.");
382*49cdfc7eSAndroid Build Coastguard Worker 		} else {	/*Process B received the signal. */
383*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Process B received the signal.");
384*49cdfc7eSAndroid Build Coastguard Worker 		}
385*49cdfc7eSAndroid Build Coastguard Worker 
386*49cdfc7eSAndroid Build Coastguard Worker 	}
387*49cdfc7eSAndroid Build Coastguard Worker 
388*49cdfc7eSAndroid Build Coastguard Worker 	else {			/*Process 2 received the signal. */
389*49cdfc7eSAndroid Build Coastguard Worker 
390*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TFAIL, "Process 2 received the signal.");
391*49cdfc7eSAndroid Build Coastguard Worker 	}
392*49cdfc7eSAndroid Build Coastguard Worker 
393*49cdfc7eSAndroid Build Coastguard Worker 	(void)par_kill();
394*49cdfc7eSAndroid Build Coastguard Worker 
395*49cdfc7eSAndroid Build Coastguard Worker 	(void)alarm(TIMEOUT);
396*49cdfc7eSAndroid Build Coastguard Worker 	while ((read(pipe1_fd[0], pipe_buf, 1) != 1) && (alarm_flag == FALSE))
397*49cdfc7eSAndroid Build Coastguard Worker 		strncpy(buf_tmp1, pipe_buf, 1);
398*49cdfc7eSAndroid Build Coastguard Worker 
399*49cdfc7eSAndroid Build Coastguard Worker }				/*End of parent_rout */
400*49cdfc7eSAndroid Build Coastguard Worker 
child1_rout(void)401*49cdfc7eSAndroid Build Coastguard Worker void child1_rout(void)
402*49cdfc7eSAndroid Build Coastguard Worker {
403*49cdfc7eSAndroid Build Coastguard Worker 	who_am_i = '1';
404*49cdfc7eSAndroid Build Coastguard Worker 
405*49cdfc7eSAndroid Build Coastguard Worker 	/*
406*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set to catch the SIGUSR1 with int1_rout.
407*49cdfc7eSAndroid Build Coastguard Worker 	 */
408*49cdfc7eSAndroid Build Coastguard Worker 	if (signal(SIGUSR1, usr1_rout) == SIG_ERR) {
409*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL,
410*49cdfc7eSAndroid Build Coastguard Worker 			 "Could not set to catch the childrens signal.");
411*49cdfc7eSAndroid Build Coastguard Worker 		(void)write(pipe1_fd[1], CHAR_SET_FAILED, 1);
412*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
413*49cdfc7eSAndroid Build Coastguard Worker 	}
414*49cdfc7eSAndroid Build Coastguard Worker 	/*
415*49cdfc7eSAndroid Build Coastguard Worker 	 *  Create children A & B.
416*49cdfc7eSAndroid Build Coastguard Worker 	 */
417*49cdfc7eSAndroid Build Coastguard Worker 	if ((pidA = tst_fork()) > 0) {
418*49cdfc7eSAndroid Build Coastguard Worker 		/*
419*49cdfc7eSAndroid Build Coastguard Worker 		 *  This is the parent(child1), fork again to create child B.
420*49cdfc7eSAndroid Build Coastguard Worker 		 */
421*49cdfc7eSAndroid Build Coastguard Worker 
422*49cdfc7eSAndroid Build Coastguard Worker 		if ((pidB = tst_fork()) == 0) {
423*49cdfc7eSAndroid Build Coastguard Worker 			/* This is child B. */
424*49cdfc7eSAndroid Build Coastguard Worker 			(void)childB_rout();
425*49cdfc7eSAndroid Build Coastguard Worker 		}
426*49cdfc7eSAndroid Build Coastguard Worker 
427*49cdfc7eSAndroid Build Coastguard Worker 		else if (pidB == -1) {
428*49cdfc7eSAndroid Build Coastguard Worker 			/*
429*49cdfc7eSAndroid Build Coastguard Worker 			 *  The fork of child B failed kill child A.
430*49cdfc7eSAndroid Build Coastguard Worker 			 */
431*49cdfc7eSAndroid Build Coastguard Worker 			if (kill(pidA, SIGKILL) == -1)
432*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TWARN,
433*49cdfc7eSAndroid Build Coastguard Worker 					 "Child process may not have been killed.");
434*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK | TERRNO, NULL, "fork failed");
435*49cdfc7eSAndroid Build Coastguard Worker 			(void)write(pipe2_fd[1], CHAR_SET_FAILED, 1);
436*49cdfc7eSAndroid Build Coastguard Worker 			exit(0);
437*49cdfc7eSAndroid Build Coastguard Worker 		}
438*49cdfc7eSAndroid Build Coastguard Worker 	}
439*49cdfc7eSAndroid Build Coastguard Worker 
440*49cdfc7eSAndroid Build Coastguard Worker 	else if (pidA == 0) {
441*49cdfc7eSAndroid Build Coastguard Worker 		/* This is child A. */
442*49cdfc7eSAndroid Build Coastguard Worker 		(void)childA_rout();
443*49cdfc7eSAndroid Build Coastguard Worker 	}
444*49cdfc7eSAndroid Build Coastguard Worker 
445*49cdfc7eSAndroid Build Coastguard Worker 	else if (pidA == -1) {
446*49cdfc7eSAndroid Build Coastguard Worker 		/*
447*49cdfc7eSAndroid Build Coastguard Worker 		 *  The fork of child A failed.
448*49cdfc7eSAndroid Build Coastguard Worker 		 */
449*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "fork failed");
450*49cdfc7eSAndroid Build Coastguard Worker 		(void)write(pipe1_fd[1], CHAR_SET_FAILED, 1);
451*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
452*49cdfc7eSAndroid Build Coastguard Worker 	}
453*49cdfc7eSAndroid Build Coastguard Worker 
454*49cdfc7eSAndroid Build Coastguard Worker 	/*
455*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set to catch the SIGUSR2 with chld1_kill.
456*49cdfc7eSAndroid Build Coastguard Worker 	 */
457*49cdfc7eSAndroid Build Coastguard Worker 	if (signal(SIGUSR2, chld1_kill) == SIG_ERR) {
458*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL,
459*49cdfc7eSAndroid Build Coastguard Worker 			 "Could not set to catch the parents signal.");
460*49cdfc7eSAndroid Build Coastguard Worker 		(void)write(pipe1_fd[1], CHAR_SET_FAILED, 1);
461*49cdfc7eSAndroid Build Coastguard Worker 		(void)chld1_kill();
462*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
463*49cdfc7eSAndroid Build Coastguard Worker 	}
464*49cdfc7eSAndroid Build Coastguard Worker 
465*49cdfc7eSAndroid Build Coastguard Worker 	/*
466*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set to catch the alarm signal SIGALRM.
467*49cdfc7eSAndroid Build Coastguard Worker 	 */
468*49cdfc7eSAndroid Build Coastguard Worker 	if (signal(SIGALRM, notify_timeout) == SIG_ERR) {
469*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL,
470*49cdfc7eSAndroid Build Coastguard Worker 			 "Could not set to catch the childs time out alarm.");
471*49cdfc7eSAndroid Build Coastguard Worker 		(void)write(pipe1_fd[1], CHAR_SET_FAILED, 1);
472*49cdfc7eSAndroid Build Coastguard Worker 		(void)chld1_kill();
473*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
474*49cdfc7eSAndroid Build Coastguard Worker 	}
475*49cdfc7eSAndroid Build Coastguard Worker 
476*49cdfc7eSAndroid Build Coastguard Worker 	/*
477*49cdfc7eSAndroid Build Coastguard Worker 	 *  Setting to catch the signals worked now let the children start up.
478*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set an alarm which causes a time out on the pipe read loop.
479*49cdfc7eSAndroid Build Coastguard Worker 	 *  The children A & B will notify the parent(child1) that set up is complete
480*49cdfc7eSAndroid Build Coastguard Worker 	 *  and the pass/fail status of set up.
481*49cdfc7eSAndroid Build Coastguard Worker 	 */
482*49cdfc7eSAndroid Build Coastguard Worker 	(void)alarm(TIMEOUT - 40);
483*49cdfc7eSAndroid Build Coastguard Worker 
484*49cdfc7eSAndroid Build Coastguard Worker 	while ((read(pipeA_fd[0], pipe_buf, 1) != 1) && (alarm_flag == FALSE))
485*49cdfc7eSAndroid Build Coastguard Worker 		/*EMPTY*/;
486*49cdfc7eSAndroid Build Coastguard Worker 	(void)alarm(TIMEOUT - 40);
487*49cdfc7eSAndroid Build Coastguard Worker 
488*49cdfc7eSAndroid Build Coastguard Worker 	while ((read(pipeB_fd[0], pipe_buf, 1) != 1) && (alarm_flag == FALSE))
489*49cdfc7eSAndroid Build Coastguard Worker 		/*EMPTY*/;
490*49cdfc7eSAndroid Build Coastguard Worker 	(void)alarm(0);		/*Reset the alarm clock. */
491*49cdfc7eSAndroid Build Coastguard Worker 
492*49cdfc7eSAndroid Build Coastguard Worker 	/*
493*49cdfc7eSAndroid Build Coastguard Worker 	 *  Check the alarm flag.
494*49cdfc7eSAndroid Build Coastguard Worker 	 */
495*49cdfc7eSAndroid Build Coastguard Worker 	if (alarm_flag == TRUE) {
496*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL,
497*49cdfc7eSAndroid Build Coastguard Worker 			 "The set up of the children failed by timing out.");
498*49cdfc7eSAndroid Build Coastguard Worker 		(void)chld1_kill();
499*49cdfc7eSAndroid Build Coastguard Worker 		(void)write(pipe1_fd[1], CHAR_SET_FAILED, 1);
500*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
501*49cdfc7eSAndroid Build Coastguard Worker 	}
502*49cdfc7eSAndroid Build Coastguard Worker 
503*49cdfc7eSAndroid Build Coastguard Worker 	/*
504*49cdfc7eSAndroid Build Coastguard Worker 	 *  Send a set up complete message to the parent.
505*49cdfc7eSAndroid Build Coastguard Worker 	 */
506*49cdfc7eSAndroid Build Coastguard Worker 	(void)write(pipe1_fd[1], CHAR_SET_PASSED, 1);
507*49cdfc7eSAndroid Build Coastguard Worker 
508*49cdfc7eSAndroid Build Coastguard Worker 	/*
509*49cdfc7eSAndroid Build Coastguard Worker 	 *  Pause until the signal SIGUSR1 or SIGUSR2 is sent from the parent.
510*49cdfc7eSAndroid Build Coastguard Worker 	 */
511*49cdfc7eSAndroid Build Coastguard Worker 	(void)pause();
512*49cdfc7eSAndroid Build Coastguard Worker 
513*49cdfc7eSAndroid Build Coastguard Worker 	/*
514*49cdfc7eSAndroid Build Coastguard Worker 	 *  Pause until signal SIGUSR2 is sent from the parent.
515*49cdfc7eSAndroid Build Coastguard Worker 	 *  This pause will only be executed if SIGUSR2 has not been received yet.
516*49cdfc7eSAndroid Build Coastguard Worker 	 */
517*49cdfc7eSAndroid Build Coastguard Worker 	while (1) {
518*49cdfc7eSAndroid Build Coastguard Worker 		sleep(1);
519*49cdfc7eSAndroid Build Coastguard Worker 	}
520*49cdfc7eSAndroid Build Coastguard Worker 
521*49cdfc7eSAndroid Build Coastguard Worker }				/*End of child1_rout */
522*49cdfc7eSAndroid Build Coastguard Worker 
523*49cdfc7eSAndroid Build Coastguard Worker /*******************************************************************************
524*49cdfc7eSAndroid Build Coastguard Worker  *  This is the routine for child 2, which should not receive the parents signal.
525*49cdfc7eSAndroid Build Coastguard Worker  ******************************************************************************/
child2_rout(void)526*49cdfc7eSAndroid Build Coastguard Worker void child2_rout(void)
527*49cdfc7eSAndroid Build Coastguard Worker {
528*49cdfc7eSAndroid Build Coastguard Worker 	who_am_i = '2';
529*49cdfc7eSAndroid Build Coastguard Worker 
530*49cdfc7eSAndroid Build Coastguard Worker 	/*
531*49cdfc7eSAndroid Build Coastguard Worker 	 * Set the process group of this process to be different
532*49cdfc7eSAndroid Build Coastguard Worker 	 * than the other processes.
533*49cdfc7eSAndroid Build Coastguard Worker 	 */
534*49cdfc7eSAndroid Build Coastguard Worker 	(void)setpgrp();
535*49cdfc7eSAndroid Build Coastguard Worker 
536*49cdfc7eSAndroid Build Coastguard Worker 	/*
537*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set to catch the SIGUSR1 with usr1_rout.
538*49cdfc7eSAndroid Build Coastguard Worker 	 */
539*49cdfc7eSAndroid Build Coastguard Worker 	if (signal(SIGUSR1, usr1_rout) == SIG_ERR) {
540*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup,
541*49cdfc7eSAndroid Build Coastguard Worker 			 "Could not set to catch the parents signal.");
542*49cdfc7eSAndroid Build Coastguard Worker 		(void)write(pipe2_fd[1], CHAR_SET_FAILED, 1);
543*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
544*49cdfc7eSAndroid Build Coastguard Worker 	}
545*49cdfc7eSAndroid Build Coastguard Worker 
546*49cdfc7eSAndroid Build Coastguard Worker 	/* Send a set up complete message to parent. */
547*49cdfc7eSAndroid Build Coastguard Worker 	(void)write(pipe2_fd[1], CHAR_SET_PASSED, 1);
548*49cdfc7eSAndroid Build Coastguard Worker 
549*49cdfc7eSAndroid Build Coastguard Worker 	/*
550*49cdfc7eSAndroid Build Coastguard Worker 	 *  Pause until killed by the parent or SIGUSR1 is received.
551*49cdfc7eSAndroid Build Coastguard Worker 	 */
552*49cdfc7eSAndroid Build Coastguard Worker 	(void)pause();
553*49cdfc7eSAndroid Build Coastguard Worker }
554*49cdfc7eSAndroid Build Coastguard Worker 
555*49cdfc7eSAndroid Build Coastguard Worker /*******************************************************************************
556*49cdfc7eSAndroid Build Coastguard Worker  *  This is the routine for child A, which should receive the parents signal.
557*49cdfc7eSAndroid Build Coastguard Worker  ******************************************************************************/
childA_rout(void)558*49cdfc7eSAndroid Build Coastguard Worker void childA_rout(void)
559*49cdfc7eSAndroid Build Coastguard Worker {
560*49cdfc7eSAndroid Build Coastguard Worker 	who_am_i = 'A';
561*49cdfc7eSAndroid Build Coastguard Worker 
562*49cdfc7eSAndroid Build Coastguard Worker 	/* Send a set up complete message to parent. */
563*49cdfc7eSAndroid Build Coastguard Worker 	write(pipeA_fd[1], CHAR_SET_PASSED, 1);
564*49cdfc7eSAndroid Build Coastguard Worker 
565*49cdfc7eSAndroid Build Coastguard Worker 	/*
566*49cdfc7eSAndroid Build Coastguard Worker 	 *  Pause until killed by the parent or SIGUSR1 is received.
567*49cdfc7eSAndroid Build Coastguard Worker 	 */
568*49cdfc7eSAndroid Build Coastguard Worker 	(void)pause();
569*49cdfc7eSAndroid Build Coastguard Worker 
570*49cdfc7eSAndroid Build Coastguard Worker 	exit(0);
571*49cdfc7eSAndroid Build Coastguard Worker }				/*End of childA_rout */
572*49cdfc7eSAndroid Build Coastguard Worker 
573*49cdfc7eSAndroid Build Coastguard Worker /*******************************************************************************
574*49cdfc7eSAndroid Build Coastguard Worker  *  This is the routine for child B, which should not receive the parents signal.
575*49cdfc7eSAndroid Build Coastguard Worker  ******************************************************************************/
childB_rout(void)576*49cdfc7eSAndroid Build Coastguard Worker void childB_rout(void)
577*49cdfc7eSAndroid Build Coastguard Worker {
578*49cdfc7eSAndroid Build Coastguard Worker 	who_am_i = 'B';
579*49cdfc7eSAndroid Build Coastguard Worker 
580*49cdfc7eSAndroid Build Coastguard Worker 	/*
581*49cdfc7eSAndroid Build Coastguard Worker 	 * Set the process group of this process to be different
582*49cdfc7eSAndroid Build Coastguard Worker 	 * than the other processes.
583*49cdfc7eSAndroid Build Coastguard Worker 	 */
584*49cdfc7eSAndroid Build Coastguard Worker 	(void)setpgrp();
585*49cdfc7eSAndroid Build Coastguard Worker 
586*49cdfc7eSAndroid Build Coastguard Worker 	/* Send a set up complete message to parent(child 1). */
587*49cdfc7eSAndroid Build Coastguard Worker 	write(pipeB_fd[1], CHAR_SET_PASSED, 1);
588*49cdfc7eSAndroid Build Coastguard Worker 
589*49cdfc7eSAndroid Build Coastguard Worker 	/*
590*49cdfc7eSAndroid Build Coastguard Worker 	 *  Pause until killed by the parent(child 1) or SIGUSR1 is received.
591*49cdfc7eSAndroid Build Coastguard Worker 	 */
592*49cdfc7eSAndroid Build Coastguard Worker 	(void)pause();
593*49cdfc7eSAndroid Build Coastguard Worker 
594*49cdfc7eSAndroid Build Coastguard Worker 	exit(0);
595*49cdfc7eSAndroid Build Coastguard Worker }
596*49cdfc7eSAndroid Build Coastguard Worker 
597*49cdfc7eSAndroid Build Coastguard Worker /*******************************************************************************
598*49cdfc7eSAndroid Build Coastguard Worker  *  This routine sets up the interprocess communication pipes, signal handling,
599*49cdfc7eSAndroid Build Coastguard Worker  *  and process group information.
600*49cdfc7eSAndroid Build Coastguard Worker  ******************************************************************************/
setup(void)601*49cdfc7eSAndroid Build Coastguard Worker void setup(void)
602*49cdfc7eSAndroid Build Coastguard Worker {
603*49cdfc7eSAndroid Build Coastguard Worker 	int errno_buf;		/*indicates the errno if pipe set up fails.             */
604*49cdfc7eSAndroid Build Coastguard Worker 	int err_flag = FALSE;	/*Indicates if an error has occurred in pipe set up.    */
605*49cdfc7eSAndroid Build Coastguard Worker 
606*49cdfc7eSAndroid Build Coastguard Worker 	/*
607*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set the process group ID to be equal between the parent and children.
608*49cdfc7eSAndroid Build Coastguard Worker 	 */
609*49cdfc7eSAndroid Build Coastguard Worker 	(void)setpgrp();
610*49cdfc7eSAndroid Build Coastguard Worker 
611*49cdfc7eSAndroid Build Coastguard Worker 	/*
612*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set to catch unexpected signals.
613*49cdfc7eSAndroid Build Coastguard Worker 	 *  SIGCHLD is set to be ignored because we do not wait for termination status.
614*49cdfc7eSAndroid Build Coastguard Worker 	 *  SIGUSR1 is set to be ignored because this is the signal we are using for
615*49cdfc7eSAndroid Build Coastguard Worker 	 *  the test and we are not concerned with the parent getting it.
616*49cdfc7eSAndroid Build Coastguard Worker 	 */
617*49cdfc7eSAndroid Build Coastguard Worker 
618*49cdfc7eSAndroid Build Coastguard Worker 	tst_sig(FORK, DEF_HANDLER, cleanup);
619*49cdfc7eSAndroid Build Coastguard Worker 
620*49cdfc7eSAndroid Build Coastguard Worker 	if (signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
621*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TFAIL, NULL,
622*49cdfc7eSAndroid Build Coastguard Worker 			 "signal(SIGUSR1, SIG_IGN) failed");
623*49cdfc7eSAndroid Build Coastguard Worker 	}
624*49cdfc7eSAndroid Build Coastguard Worker 
625*49cdfc7eSAndroid Build Coastguard Worker 	if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
626*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL,
627*49cdfc7eSAndroid Build Coastguard Worker 			 "signal(SIGCHLD, SIG_IGN) failed");
628*49cdfc7eSAndroid Build Coastguard Worker 	}
629*49cdfc7eSAndroid Build Coastguard Worker 
630*49cdfc7eSAndroid Build Coastguard Worker 	TEST_PAUSE;
631*49cdfc7eSAndroid Build Coastguard Worker 
632*49cdfc7eSAndroid Build Coastguard Worker 	/*
633*49cdfc7eSAndroid Build Coastguard Worker 	 *  Set up pipe1, pipe2, pipeA, and pipeB.
634*49cdfc7eSAndroid Build Coastguard Worker 	 */
635*49cdfc7eSAndroid Build Coastguard Worker 	if ((pipe(pipe1_fd) == -1)
636*49cdfc7eSAndroid Build Coastguard Worker 	    || (fcntl(pipe1_fd[0], F_SETFL, O_NDELAY) == -1)) {
637*49cdfc7eSAndroid Build Coastguard Worker 		errno_buf = errno;
638*49cdfc7eSAndroid Build Coastguard Worker 		err_flag = TRUE;
639*49cdfc7eSAndroid Build Coastguard Worker 	}
640*49cdfc7eSAndroid Build Coastguard Worker 
641*49cdfc7eSAndroid Build Coastguard Worker 	if ((pipe(pipe2_fd) == -1)
642*49cdfc7eSAndroid Build Coastguard Worker 	    || (fcntl(pipe2_fd[0], F_SETFL, O_NDELAY) == -1)) {
643*49cdfc7eSAndroid Build Coastguard Worker 		errno_buf = errno;
644*49cdfc7eSAndroid Build Coastguard Worker 		err_flag = TRUE;
645*49cdfc7eSAndroid Build Coastguard Worker 	}
646*49cdfc7eSAndroid Build Coastguard Worker 
647*49cdfc7eSAndroid Build Coastguard Worker 	if ((pipe(pipeA_fd) == -1)
648*49cdfc7eSAndroid Build Coastguard Worker 	    || (fcntl(pipeA_fd[0], F_SETFL, O_NDELAY) == -1)) {
649*49cdfc7eSAndroid Build Coastguard Worker 		errno_buf = errno;
650*49cdfc7eSAndroid Build Coastguard Worker 		err_flag = TRUE;
651*49cdfc7eSAndroid Build Coastguard Worker 	}
652*49cdfc7eSAndroid Build Coastguard Worker 
653*49cdfc7eSAndroid Build Coastguard Worker 	if ((pipe(pipeB_fd) == -1)
654*49cdfc7eSAndroid Build Coastguard Worker 	    || (fcntl(pipeB_fd[0], F_SETFL, O_NDELAY) == -1)) {
655*49cdfc7eSAndroid Build Coastguard Worker 		errno_buf = errno;
656*49cdfc7eSAndroid Build Coastguard Worker 		err_flag = TRUE;
657*49cdfc7eSAndroid Build Coastguard Worker 	}
658*49cdfc7eSAndroid Build Coastguard Worker 
659*49cdfc7eSAndroid Build Coastguard Worker 	/*
660*49cdfc7eSAndroid Build Coastguard Worker 	 *  Check for errors.
661*49cdfc7eSAndroid Build Coastguard Worker 	 */
662*49cdfc7eSAndroid Build Coastguard Worker 	if (err_flag == TRUE) {
663*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "pipe() failed");
664*49cdfc7eSAndroid Build Coastguard Worker 	}
665*49cdfc7eSAndroid Build Coastguard Worker 	return;
666*49cdfc7eSAndroid Build Coastguard Worker 
667*49cdfc7eSAndroid Build Coastguard Worker }
668*49cdfc7eSAndroid Build Coastguard Worker 
669*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************
670*49cdfc7eSAndroid Build Coastguard Worker  *  This routine indicates that the process caught SIGUSR1.
671*49cdfc7eSAndroid Build Coastguard Worker  **********************************************************/
usr1_rout(void)672*49cdfc7eSAndroid Build Coastguard Worker void usr1_rout(void)
673*49cdfc7eSAndroid Build Coastguard Worker {
674*49cdfc7eSAndroid Build Coastguard Worker 	switch (who_am_i) {
675*49cdfc7eSAndroid Build Coastguard Worker 	case '1':
676*49cdfc7eSAndroid Build Coastguard Worker 		if (write(pipe1_fd[1], SIG_CAUGHT, 1) == -1)
677*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TWARN,
678*49cdfc7eSAndroid Build Coastguard Worker 				 "Writing signal catching status failed in child 1.");
679*49cdfc7eSAndroid Build Coastguard Worker 		break;
680*49cdfc7eSAndroid Build Coastguard Worker 	case '2':
681*49cdfc7eSAndroid Build Coastguard Worker 		if (write(pipe2_fd[1], SIG_CAUGHT, 1) == -1)
682*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TWARN,
683*49cdfc7eSAndroid Build Coastguard Worker 				 "Writing signal catching status failed in child 2.");
684*49cdfc7eSAndroid Build Coastguard Worker 		break;
685*49cdfc7eSAndroid Build Coastguard Worker 	case 'A':
686*49cdfc7eSAndroid Build Coastguard Worker 		if (write(pipeA_fd[1], SIG_CAUGHT, 1) == -1)
687*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TWARN,
688*49cdfc7eSAndroid Build Coastguard Worker 				 "Writing signal catching status failed in child A.");
689*49cdfc7eSAndroid Build Coastguard Worker 		break;
690*49cdfc7eSAndroid Build Coastguard Worker 	case 'B':
691*49cdfc7eSAndroid Build Coastguard Worker 		if (write(pipeB_fd[1], SIG_CAUGHT, 1) == -1)
692*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TWARN,
693*49cdfc7eSAndroid Build Coastguard Worker 				 "Writing signal catching status failed in child B.");
694*49cdfc7eSAndroid Build Coastguard Worker 		break;
695*49cdfc7eSAndroid Build Coastguard Worker 	default:
696*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN,
697*49cdfc7eSAndroid Build Coastguard Worker 			 "Unexpected value %d for who_am_i in usr1_rout()",
698*49cdfc7eSAndroid Build Coastguard Worker 			 who_am_i);
699*49cdfc7eSAndroid Build Coastguard Worker 		break;
700*49cdfc7eSAndroid Build Coastguard Worker 	}
701*49cdfc7eSAndroid Build Coastguard Worker 
702*49cdfc7eSAndroid Build Coastguard Worker }				/*End of usr1_rout */
703*49cdfc7eSAndroid Build Coastguard Worker 
704*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************
705*49cdfc7eSAndroid Build Coastguard Worker  *  This routine handles the timeout alarm in the parent,
706*49cdfc7eSAndroid Build Coastguard Worker  *  which occurs when the child fails to notify the parent
707*49cdfc7eSAndroid Build Coastguard Worker  *  the status of set up.
708*49cdfc7eSAndroid Build Coastguard Worker  **********************************************************/
notify_timeout(void)709*49cdfc7eSAndroid Build Coastguard Worker void notify_timeout(void)
710*49cdfc7eSAndroid Build Coastguard Worker {
711*49cdfc7eSAndroid Build Coastguard Worker 	alarm_flag = TRUE;
712*49cdfc7eSAndroid Build Coastguard Worker 
713*49cdfc7eSAndroid Build Coastguard Worker }				/*End of notify_timeout */
714*49cdfc7eSAndroid Build Coastguard Worker 
715*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************
716*49cdfc7eSAndroid Build Coastguard Worker  *  This routine handles the procedure for removing the
717*49cdfc7eSAndroid Build Coastguard Worker  *  children forked off during this test.
718*49cdfc7eSAndroid Build Coastguard Worker  **********************************************************/
par_kill(void)719*49cdfc7eSAndroid Build Coastguard Worker void par_kill(void)
720*49cdfc7eSAndroid Build Coastguard Worker {
721*49cdfc7eSAndroid Build Coastguard Worker 	int status;
722*49cdfc7eSAndroid Build Coastguard Worker 
723*49cdfc7eSAndroid Build Coastguard Worker 	/*
724*49cdfc7eSAndroid Build Coastguard Worker 	 *  Indicate to child1 that it can remove it's children and itself now.
725*49cdfc7eSAndroid Build Coastguard Worker 	 */
726*49cdfc7eSAndroid Build Coastguard Worker 	if (kill(pid1, SIGUSR2) == -1 && errno != ESRCH) {
727*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN | TERRNO, "kill() failed");
728*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN,
729*49cdfc7eSAndroid Build Coastguard Worker 			 "Child 1 and it's children may still be alive.");
730*49cdfc7eSAndroid Build Coastguard Worker 	}
731*49cdfc7eSAndroid Build Coastguard Worker 
732*49cdfc7eSAndroid Build Coastguard Worker 	/*
733*49cdfc7eSAndroid Build Coastguard Worker 	 *  Remove child 2.
734*49cdfc7eSAndroid Build Coastguard Worker 	 */
735*49cdfc7eSAndroid Build Coastguard Worker 	if (kill(pid2, SIGKILL) == -1 && errno != ESRCH)
736*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN, "Child2 may still be alive.");
737*49cdfc7eSAndroid Build Coastguard Worker 
738*49cdfc7eSAndroid Build Coastguard Worker 	wait(&status);
739*49cdfc7eSAndroid Build Coastguard Worker 	return;
740*49cdfc7eSAndroid Build Coastguard Worker 
741*49cdfc7eSAndroid Build Coastguard Worker }				/*End of par_kill */
742*49cdfc7eSAndroid Build Coastguard Worker 
743*49cdfc7eSAndroid Build Coastguard Worker /*********************************************************************
744*49cdfc7eSAndroid Build Coastguard Worker  *  This routine is executed by child 1 when the parent tells it to
745*49cdfc7eSAndroid Build Coastguard Worker  *  remove it's children and itself.
746*49cdfc7eSAndroid Build Coastguard Worker  ********************************************************************/
chld1_kill(void)747*49cdfc7eSAndroid Build Coastguard Worker void chld1_kill(void)
748*49cdfc7eSAndroid Build Coastguard Worker {
749*49cdfc7eSAndroid Build Coastguard Worker 	/*
750*49cdfc7eSAndroid Build Coastguard Worker 	 *  Remove children A & B.
751*49cdfc7eSAndroid Build Coastguard Worker 	 */
752*49cdfc7eSAndroid Build Coastguard Worker 	if (kill(pidA, SIGKILL) == -1 && errno != ESRCH)
753*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN | TERRNO,
754*49cdfc7eSAndroid Build Coastguard Worker 			 "kill(%d) failed; child 1's(A) child may still be alive",
755*49cdfc7eSAndroid Build Coastguard Worker 			 pidA);
756*49cdfc7eSAndroid Build Coastguard Worker 
757*49cdfc7eSAndroid Build Coastguard Worker 	(void)write(pipe1_fd[1], CHAR_SET_PASSED, 1);
758*49cdfc7eSAndroid Build Coastguard Worker 
759*49cdfc7eSAndroid Build Coastguard Worker 	if (kill(pidB, SIGKILL) == -1 && errno != ESRCH)
760*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN | TERRNO,
761*49cdfc7eSAndroid Build Coastguard Worker 			 "kill(%d) failed; child 1's(B) child may still be alive",
762*49cdfc7eSAndroid Build Coastguard Worker 			 pidB);
763*49cdfc7eSAndroid Build Coastguard Worker 
764*49cdfc7eSAndroid Build Coastguard Worker 	exit(0);
765*49cdfc7eSAndroid Build Coastguard Worker 
766*49cdfc7eSAndroid Build Coastguard Worker }				/*End of chld1_kill */
767*49cdfc7eSAndroid Build Coastguard Worker 
768*49cdfc7eSAndroid Build Coastguard Worker /***************************************************************
769*49cdfc7eSAndroid Build Coastguard Worker  * cleanup() - performs all ONE TIME cleanup for this test at
770*49cdfc7eSAndroid Build Coastguard Worker  *              completion or premature exit.
771*49cdfc7eSAndroid Build Coastguard Worker  ***************************************************************/
cleanup(void)772*49cdfc7eSAndroid Build Coastguard Worker void cleanup(void)
773*49cdfc7eSAndroid Build Coastguard Worker {
774*49cdfc7eSAndroid Build Coastguard Worker 
775*49cdfc7eSAndroid Build Coastguard Worker }
776