• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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