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