kill08.c revision e1f008ec81a2828dfb2113ce97347946f42e9f3e
1/* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20/* 21 * NAME 22 * kill08.c 23 * 24 * DESCRIPTION 25 * Test case to check the basic functionality of kill() when kill an 26 * entire process group. 27 * 28 * ALGORITHM 29 * call setup 30 * loop if the -i option was given 31 * fork 5 childeren 32 * execute the kill system call 33 * check the return value 34 * if return value is -1 35 * issue a FAIL message, break remaining tests and cleanup 36 * if we are doing functional testing 37 * if the processes were terminated with the expected signal. 38 * issue a PASS message 39 * otherwise 40 * issue a FAIL message 41 * call cleanup 42 * 43 * USAGE 44 * kill08 [-c n] [-f] [-i n] [-I x] [-P x] [-t] 45 * where, -c n : Run n copies concurrently. 46 * -f : Turn off functionality Testing. 47 * -i n : Execute test n times. 48 * -I x : Execute test for x seconds. 49 * -P x : Pause for x seconds between iterations. 50 * -t : Turn on syscall timing. 51 * 52 * HISTORY 53 * 07/2001 Ported by Wayne Boyer 54 * 55 * RESTRICTIONS 56 * This test should be run as a non-root user. 57 */ 58 59#include "test.h" 60#include "usctest.h" 61 62#include <signal.h> 63#include <errno.h> 64#include <sys/wait.h> 65 66void cleanup(void); 67void setup(void); 68void do_child(void); 69 70char *TCID = "kill08"; 71int TST_TOTAL = 1; 72 73extern int Tst_count; 74 75#define TEST_SIG SIGKILL 76 77int main(int ac, char **av) 78{ 79 int lc; /* loop counter */ 80 char *msg; /* message returned from parse_opts */ 81 pid_t pid1, pid2; 82 int exno, status, nsig, i; 83 84 /* parse standard options */ 85 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { 86 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); 87 } 88#ifdef UCLINUX 89 maybe_run_child(&do_child, ""); 90#endif 91 92 setup(); /* global setup */ 93 94 /* The following loop checks looping state if -i option given */ 95 for (lc = 0; TEST_LOOPING(lc); lc++) { 96 97 /* reset Tst_count in case we are looping */ 98 Tst_count = 0; 99 status = 1; 100 exno = 1; 101 102 /* Fork a process and set the process group so that */ 103 /* it is different from this one. Fork 5 more children. */ 104 105 pid1 = FORK_OR_VFORK(); 106 if (pid1 < 0) { 107 tst_brkm(TBROK, cleanup, "Fork of first child failed"); 108 } else if (pid1 == 0) { 109 setpgrp(); 110 for (i = 0; i < 5; i++) { 111 pid2 = FORK_OR_VFORK(); 112 if (pid2 < 0) { 113 tst_brkm(TBROK, cleanup, "Fork failed"); 114 } else if (pid2 == 0) { 115#ifdef UCLINUX 116 if (self_exec(av[0], "") < 0) { 117 tst_brkm(TBROK, cleanup, 118 "self_exec of " 119 "child failed"); 120 } 121#else 122 do_child(); 123#endif 124 } 125 } 126 /* Kill all processes in this process group */ 127 TEST(kill(0, TEST_SIG)); 128 pause(); 129 /*NOTREACHED*/ exit(exno); 130 } else { 131 waitpid(pid1, &status, 0); 132 if (TEST_RETURN != 0) { 133 tst_brkm(TFAIL, cleanup, "%s failed - errno = " 134 "%d : %s", TCID, TEST_ERRNO, 135 strerror(TEST_ERRNO)); 136 } 137 } 138 139 if (STD_FUNCTIONAL_TEST) { 140 /* 141 * Check to see if the process was terminated with the 142 * expected signal. 143 */ 144 nsig = WTERMSIG(status); 145 if (nsig == TEST_SIG) { 146 tst_resm(TPASS, "received expected signal %d", 147 nsig); 148 } else { 149 tst_resm(TFAIL, 150 "expected signal %d received %d", 151 TEST_SIG, nsig); 152 } 153 } else { 154 tst_resm(TPASS, "call succeeded"); 155 } 156 } 157 cleanup(); 158 159 /*NOTREACHED*/ return 0; 160} 161 162/* 163 * do_child() 164 */ 165void do_child() 166{ 167 int exno = 1; 168 169 pause(); 170 /*NOTREACHED*/ exit(exno); 171} 172 173/* 174 * setup() - performs all ONE TIME setup for this test 175 */ 176void setup(void) 177{ 178 /* Pause if that option was specified */ 179 TEST_PAUSE; 180} 181 182/* 183 * cleanup() - performs all the ONE TIME cleanup for this test at completion 184 * or premature exit. 185 */ 186void cleanup(void) 187{ 188 /* 189 * print timing status if that option was specified. 190 * print errno log if that option was specified 191 */ 192 TEST_CLEANUP; 193 194 /* exit with return code appropriate for results */ 195 tst_exit(); 196} 197