1 /* IBM Corporation 2 * 01/02/2003 Port to LTP avenkat (at) us.ibm.com 3 * 06/30/2001 Port to Linux nsharoff (at) us.ibm.com 4 * 5 * Copyright (c) International Business Machines Corp., 2002 6 * Copyright (c) Cyril Hrubis <chrubis (at) suse.cz> 2014 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 16 * the GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 /* 24 25 Test check that when a child is killed by its parent, it returns the correct 26 values to the waiting parent--default behaviour assumed by child. 27 28 */ 29 30 #define _GNU_SOURCE 1 31 32 #include <stdio.h> 33 #include <errno.h> 34 #include <sys/types.h> 35 #include <signal.h> 36 #include <stdlib.h> 37 #include <unistd.h> 38 #include <sys/wait.h> 39 #include <sys/resource.h> 40 41 #include "test.h" 42 #include "safe_macros.h" 43 44 #define FAILED 0 45 #define PASSED 1 46 47 char *TCID = "kill11"; 48 49 int local_flag = PASSED; 50 int block_number; 51 FILE *temp; 52 int TST_TOTAL = 1; 53 static int sig; 54 55 void setup(void); 56 void do_child(void); 57 58 /* 59 * These signals terminate process by default, some create core file. 60 */ 61 struct tcase { 62 int sig; 63 int dumps_core; 64 } tcases[] = { 65 {SIGHUP, 0}, 66 {SIGINT, 0}, 67 {SIGQUIT, 1}, 68 {SIGILL, 1}, 69 {SIGTRAP, 1}, 70 {SIGABRT, 1}, 71 {SIGIOT, 1}, 72 {SIGBUS, 1}, 73 {SIGFPE, 1}, 74 {SIGKILL, 0}, 75 {SIGUSR1, 0}, 76 {SIGSEGV, 1}, 77 {SIGUSR2, 0}, 78 {SIGPIPE, 0}, 79 {SIGALRM, 0}, 80 {SIGTERM, 0}, 81 {SIGXCPU, 1}, 82 {SIGXFSZ, 1}, 83 {SIGVTALRM, 0}, 84 {SIGPROF, 0}, 85 {SIGIO, 0}, 86 {SIGPWR, 0}, 87 {SIGSYS, 1}, 88 }; 89 90 static void verify_kill(struct tcase *t) 91 { 92 int core; 93 int pid, npid; 94 int nsig, nexno, status; 95 96 if (t->sig != SIGKILL) { 97 #ifndef BCS 98 if (t->sig != SIGSTOP) 99 #endif 100 if (sigset(t->sig, SIG_DFL) == SIG_ERR) { 101 tst_brkm(TBROK | TERRNO, tst_rmdir, 102 "sigset(%d) failed", sig); 103 } 104 } 105 106 pid = FORK_OR_VFORK(); 107 if (pid < 0) 108 tst_brkm(TBROK | TERRNO, tst_rmdir, "fork() failed"); 109 110 if (pid == 0) { 111 #ifdef UCLINUX 112 if (self_exec(argv[0], "dd", t->sig) < 0) 113 exit(1); 114 #else 115 do_child(); 116 #endif 117 } 118 119 kill(pid, t->sig); 120 npid = wait(&status); 121 122 if (npid != pid) { 123 tst_resm(TFAIL, "wait() returned %d, expected %d", npid, pid); 124 return; 125 } 126 127 nsig = WTERMSIG(status); 128 #ifdef WCOREDUMP 129 core = WCOREDUMP(status); 130 #endif 131 nexno = WIFEXITED(status); 132 133 if (t->dumps_core) { 134 if (!core) { 135 tst_resm(TFAIL, "core dump bit not set for %s", tst_strsig(t->sig)); 136 return; 137 } 138 } else { 139 if (core) { 140 tst_resm(TFAIL, "core dump bit set for %s", tst_strsig(t->sig)); 141 return; 142 } 143 } 144 145 if (nsig != t->sig) { 146 tst_resm(TFAIL, "wait: unexpected signal %d returned, expected %d", nsig, t->sig); 147 return; 148 } 149 150 if (nexno != 0) { 151 tst_resm(TFAIL, 152 "signal: unexpected exit number %d returned, expected 0\n", 153 nexno); 154 return; 155 } 156 157 tst_resm(TPASS, "signal %-16s%s", tst_strsig(t->sig), 158 t->dumps_core ? " dumped core" : ""); 159 } 160 161 int main(int argc, char **argv) 162 { 163 int lc; 164 unsigned int i; 165 166 tst_parse_opts(argc, argv, NULL, NULL); 167 168 #ifdef UCLINUX 169 maybe_run_child(&do_child, "dd", &sig); 170 #endif 171 172 setup(); 173 174 for (lc = 0; TEST_LOOPING(lc); lc++) { 175 for (i = 0; i < ARRAY_SIZE(tcases); i++) 176 verify_kill(tcases + i); 177 } 178 179 tst_rmdir(); 180 tst_exit(); 181 } 182 183 void do_child(void) 184 { 185 int i; 186 187 for (i = 0; i < 180; i++) 188 sleep(1); 189 190 fprintf(stderr, "Child missed siggnal"); 191 fflush(stderr); 192 exit(1); 193 } 194 195 /* 1024 GNU blocks */ 196 #define MIN_RLIMIT_CORE (1024 * 1024) 197 198 void setup(void) 199 { 200 struct rlimit rlim; 201 202 SAFE_GETRLIMIT(NULL, RLIMIT_CORE, &rlim); 203 204 if (rlim.rlim_cur < MIN_RLIMIT_CORE) { 205 tst_resm(TINFO, "Adjusting RLIMIT_CORE to %i", MIN_RLIMIT_CORE); 206 rlim.rlim_cur = MIN_RLIMIT_CORE; 207 SAFE_SETRLIMIT(NULL, RLIMIT_CORE, &rlim); 208 } 209 210 temp = stderr; 211 tst_tmpdir(); 212 } 213