Home | History | Annotate | Download | only in waitpid
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2001
      4  *
      5  *   This program is free software;  you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 2 of the License, or
      8  *   (at your option) any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     13  *   the GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program;  if not, write to the Free Software
     17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     18  */
     19 
     20 /*
     21  * NAME
     22  *	waitpid02.c
     23  *
     24  * DESCRIPTION
     25  *	Check that when a child gets killed by an integer zero
     26  *	divide exception, the waiting parent is correctly notified.
     27  *
     28  * ALGORITHM
     29  *	Fork a child and send a SIGFPE to it. The parent waits for the
     30  *	death of the child and checks that SIGFPE was returned.
     31  *
     32  * USAGE:  <for command-line>
     33  *      waitpid02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
     34  *      where,  -c n : Run n copies concurrently.
     35  *              -e   : Turn on errno logging.
     36  *              -i n : Execute test n times.
     37  *              -I x : Execute test for x seconds.
     38  *              -P x : Pause for x seconds between iterations.
     39  *              -t   : Turn on syscall timing.
     40  *
     41  * History
     42  *	07/2001 John George
     43  *		-Ported
     44  *	10/2002 Paul Larson
     45  *		Div by zero doesn't cause SIGFPE on some archs, fixed
     46  *		to send the signal with kill
     47  *
     48  * Restrictions
     49  *	None
     50  */
     51 
     52 #include <sys/file.h>
     53 #include <sys/resource.h>
     54 #include <sys/signal.h>
     55 #include <sys/types.h>
     56 #include <sys/wait.h>
     57 #include <errno.h>
     58 #include "test.h"
     59 
     60 static void do_child(void);
     61 static void setup(void);
     62 
     63 char *TCID = "waitpid02";
     64 int TST_TOTAL = 1;
     65 
     66 int main(int argc, char **argv)
     67 {
     68 	int lc;
     69 
     70 	int pid, npid, sig, nsig;
     71 	int nexno, status;
     72 
     73 	tst_parse_opts(argc, argv, NULL, NULL);
     74 #ifdef UCLINUX
     75 	maybe_run_child(&do_child, "");
     76 #endif
     77 
     78 	setup();
     79 
     80 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     81 		tst_count = 0;
     82 
     83 		sig = SIGFPE;
     84 
     85 		pid = FORK_OR_VFORK();
     86 
     87 		if (pid < 0)
     88 			tst_brkm(TBROK|TERRNO, NULL, "fork failed");
     89 
     90 		if (pid == 0) {
     91 #ifdef UCLINUX
     92 			self_exec(argv[0], "");
     93 			/* No fork() error check is done so don't check here */
     94 #else
     95 			do_child();
     96 #endif
     97 		} else {
     98 			kill(pid, sig);
     99 			errno = 0;
    100 			while (((npid = waitpid(pid, &status, 0)) != -1) ||
    101 			       (errno == EINTR)) {
    102 				if (errno == EINTR)
    103 					continue;
    104 
    105 				if (npid != pid) {
    106 					tst_resm(TFAIL, "waitpid error: "
    107 						 "unexpected pid returned");
    108 				} else {
    109 					tst_resm(TPASS,
    110 						 "recieved expected pid");
    111 				}
    112 
    113 				nsig = WTERMSIG(status);
    114 
    115 				/*
    116 				 * nsig is the signal number returned by
    117 				 * waitpid
    118 				 */
    119 				if (nsig != sig) {
    120 					tst_resm(TFAIL, "waitpid error: "
    121 						 "unexpected signal returned");
    122 				} else {
    123 					tst_resm(TPASS, "recieved expected "
    124 						 "signal");
    125 				}
    126 
    127 				/*
    128 				 * nexno is the exit number returned by
    129 				 * waitpid
    130 				 */
    131 				nexno = WEXITSTATUS(status);
    132 				if (nexno != 0) {
    133 					tst_resm(TFAIL, "signal error: "
    134 						 "unexpected exit number "
    135 						 "returned");
    136 				} else {
    137 					tst_resm(TPASS, "recieved expected "
    138 						 "exit value");
    139 				}
    140 			}
    141 		}
    142 	}
    143 
    144 	tst_exit();
    145 }
    146 
    147 static void do_child(void)
    148 {
    149 	int exno = 1;
    150 
    151 	while (1)
    152 		usleep(10);
    153 
    154 	exit(exno);
    155 }
    156 
    157 static void setup(void)
    158 {
    159 	/* SIGFPE is expected signal, so avoid creating any corefile.
    160 	 * '1' is a special value, that will also avoid dumping via pipe. */
    161 	struct rlimit r;
    162 	r.rlim_cur = 1;
    163 	r.rlim_max = 1;
    164 	setrlimit(RLIMIT_CORE, &r);
    165 
    166 	TEST_PAUSE;
    167 }
    168