Home | History | Annotate | Download | only in abort
      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