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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * NAME 22 * kill06.c 23 * 24 * DESCRIPTION 25 * Test case to check the basic functionality of kill() when killing an 26 * entire process group with a negative pid. 27 * 28 * ALGORITHM 29 * call setup 30 * loop if the -i option was given 31 * fork 5 children 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 * kill06 [-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 61 #include <signal.h> 62 #include <errno.h> 63 #include <sys/wait.h> 64 65 void cleanup(void); 66 void setup(void); 67 void do_child(void); 68 69 char *TCID = "kill06"; 70 int TST_TOTAL = 1; 71 72 #define TEST_SIG SIGKILL 73 74 int main(int ac, char **av) 75 { 76 int lc; 77 pid_t pid1, pid2; 78 int exno, status, nsig, i; 79 80 tst_parse_opts(ac, av, NULL, NULL); 81 #ifdef UCLINUX 82 maybe_run_child(&do_child, ""); 83 #endif 84 85 setup(); /* global setup */ 86 87 /* The following loop checks looping state if -i option given */ 88 for (lc = 0; TEST_LOOPING(lc); lc++) { 89 90 /* reset tst_count in case we are looping */ 91 tst_count = 0; 92 status = 1; 93 exno = 1; 94 95 /* Fork a process and set the process group so that */ 96 /* it is different from this one. Fork 5 more children. */ 97 98 pid1 = FORK_OR_VFORK(); 99 if (pid1 < 0) { 100 tst_brkm(TBROK, cleanup, "Fork of first child failed"); 101 } else if (pid1 == 0) { 102 setpgrp(); 103 for (i = 0; i < 5; i++) { 104 pid2 = FORK_OR_VFORK(); 105 if (pid2 < 0) { 106 tst_brkm(TBROK, cleanup, "Fork failed"); 107 } else if (pid2 == 0) { 108 #ifdef UCLINUX 109 if (self_exec(av[0], "") < 0) { 110 tst_brkm(TBROK, cleanup, 111 "self_exec of " 112 "child failed"); 113 } 114 #else 115 do_child(); 116 #endif 117 } 118 } 119 /* Kill all processes in this process group */ 120 TEST(kill(-getpgrp(), TEST_SIG)); 121 sleep(300); 122 123 tst_resm(TINFO, "%d never recieved a" 124 " signal", getpid()); 125 exit(exno); 126 } else { 127 waitpid(pid1, &status, 0); 128 if (TEST_RETURN != 0) { 129 tst_brkm(TFAIL, cleanup, "%s failed - errno = " 130 "%d : %s", TCID, TEST_ERRNO, 131 strerror(TEST_ERRNO)); 132 } 133 } 134 135 /* 136 * Check to see if the process was terminated with the 137 * expected signal. 138 */ 139 nsig = WTERMSIG(status); 140 if (!nsig) { 141 tst_resm(TFAIL, "Did not receive any signal"); 142 } else if (nsig == TEST_SIG) { 143 tst_resm(TPASS, "received expected signal %d", 144 nsig); 145 } else { 146 tst_resm(TFAIL, 147 "expected signal %d received %d", 148 TEST_SIG, nsig); 149 } 150 } 151 152 cleanup(); 153 tst_exit(); 154 } 155 156 /* 157 * do_child() 158 */ 159 void do_child(void) 160 { 161 int exno = 1; 162 163 sleep(299); 164 165 tst_resm(TINFO, "%d never recieved a" " signal", getpid()); 166 exit(exno); 167 } 168 169 /* 170 * setup() - performs all ONE TIME setup for this test 171 */ 172 void setup(void) 173 { 174 /* Setup default signal handling */ 175 tst_sig(FORK, DEF_HANDLER, cleanup); 176 177 TEST_PAUSE; 178 } 179 180 /* 181 * cleanup() - performs all the ONE TIME cleanup for this test at completion 182 * or premature exit. 183 */ 184 void cleanup(void) 185 { 186 187 } 188