1 /*
2 * Copyright (c) International Business Machines Corp., 2002
3 * 01/02/2003 Port to LTP avenkat@us.ibm.com
4 * 11/11/2002: Ported to LTP Suite by Ananda
5 * 06/30/2001 Port to Linux nsharoff@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
main(int argc,char * argv[])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
setup(void)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
cleanup(void)148 static void cleanup(void)
149 {
150 unlink("core");
151 tst_rmdir();
152 }
153
do_child(void)154 static void do_child(void)
155 {
156 abort();
157 fprintf(stderr, "\tchild - abort failed.\n");
158 exit(1);
159 }
160
instress(void)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