1 /* 2 * Copyright (c) International Business Machines Corp., 2002 3 * 01/02/2003 Port to LTP avenkat (at) us.ibm.com 4 * 11/11/2002: Ported to LTP Suite by Ananda 5 * 06/30/2001 Port to Linux nsharoff (at) us.ibm.com 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 * the GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22 /* ALGORITHM 23 * Fork child. Have child abort, check return status. 24 * 25 * RESTRICTIONS 26 * The ulimit for core file size must be greater than 0. 27 */ 28 29 #include <sys/types.h> 30 #include <sys/wait.h> 31 #include <errno.h> 32 #include <signal.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <unistd.h> 36 #include <sys/resource.h> 37 38 #include "test.h" 39 #include "safe_macros.h" 40 41 #define NUM 3 42 43 char *TCID = "abort01"; 44 int TST_TOTAL = 1; 45 46 static void setup(void); 47 static void cleanup(void); 48 static void do_child(); 49 static int instress(); 50 51 int main(int argc, char *argv[]) 52 { 53 register int i; 54 int status, count, child, kidpid; 55 int sig, ex; 56 57 #ifdef WCOREDUMP 58 int core; 59 core = 0; 60 #endif 61 ex = sig = 0; 62 63 tst_parse_opts(argc, argv, NULL, NULL); 64 #ifdef UCLINUX 65 maybe_run_child(&do_child, ""); 66 #endif 67 68 setup(); 69 70 for (i = 0; i < NUM; i++) { 71 kidpid = FORK_OR_VFORK(); 72 if (kidpid == 0) { 73 #ifdef UCLINUX 74 if (self_exec(argv[0], "")) { 75 if (!instress()) { 76 perror("fork failed"); 77 exit(1); 78 } 79 } 80 #else 81 do_child(); 82 #endif 83 } 84 if (kidpid < 0) 85 if (!instress()) 86 tst_brkm(TBROK | TERRNO, cleanup, 87 "fork failed"); 88 count = 0; 89 while ((child = wait(&status)) > 0) 90 count++; 91 if (count != 1) { 92 tst_brkm(TBROK, cleanup, 93 "wrong # children waited on; got %d, expected 1", 94 count); 95 } 96 if (WIFSIGNALED(status)) { 97 98 #ifdef WCOREDUMP 99 core = WCOREDUMP(status); 100 #endif 101 sig = WTERMSIG(status); 102 103 } 104 if (WIFEXITED(status)) 105 ex = WEXITSTATUS(status); 106 107 #ifdef WCOREDUMP 108 if (core == 0) { 109 tst_brkm(TFAIL, cleanup, 110 "Child did not dump core; exit code = %d, " 111 "signal = %d", ex, sig); 112 } else if (core != -1) { 113 tst_resm(TPASS, "abort dumped core"); 114 } 115 #endif 116 if (sig == SIGIOT) { 117 tst_resm(TPASS, "abort raised SIGIOT"); 118 } else { 119 tst_brkm(TFAIL, cleanup, 120 "Child did not raise SIGIOT (%d); exit code = %d, " 121 "signal = %d", SIGIOT, ex, sig); 122 } 123 124 } 125 126 cleanup(); 127 tst_exit(); 128 } 129 130 /* 1024 GNU blocks */ 131 #define MIN_RLIMIT_CORE (1024 * 1024) 132 133 static void setup(void) 134 { 135 struct rlimit rlim; 136 137 SAFE_GETRLIMIT(NULL, RLIMIT_CORE, &rlim); 138 139 if (rlim.rlim_cur < MIN_RLIMIT_CORE) { 140 tst_resm(TINFO, "Adjusting RLIMIT_CORE to %i", MIN_RLIMIT_CORE); 141 rlim.rlim_cur = MIN_RLIMIT_CORE; 142 SAFE_SETRLIMIT(NULL, RLIMIT_CORE, &rlim); 143 } 144 145 tst_tmpdir(); 146 } 147 148 static void cleanup(void) 149 { 150 unlink("core"); 151 tst_rmdir(); 152 } 153 154 static void do_child(void) 155 { 156 abort(); 157 fprintf(stderr, "\tchild - abort failed.\n"); 158 exit(1); 159 } 160 161 static int instress(void) 162 { 163 tst_resm(TINFO, 164 "System resources may be too low; fork(), select() etc are likely to fail."); 165 return 1; 166 } 167