1cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz/*
2cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   Copyright (c) International Business Machines  Corp., 2001
3cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *
4cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   This program is free software;  you can redistribute it and/or modify
5cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   it under the terms of the GNU General Public License as published by
6cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   the Free Software Foundation; either version 2 of the License, or
7cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   (at your option) any later version.
8cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *
9cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   This program is distributed in the hope that it will be useful,
10cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   the GNU General Public License for more details.
13cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *
14cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   You should have received a copy of the GNU General Public License
15cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *   along with this program;  if not, write to the Free Software
164548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
179ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *
189ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *
19cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz * NAME
209ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *	fork12.c
21cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *
22cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz * DESCRIPTION
23cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *	Check that all children inherit parent's file descriptor
24cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *
25cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz * ALGORITHM
269ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *	Parent forks processes until -1 is returned.$
279ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *
28cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz * USAGE
299ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *	fork12
309ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *	** CAUTION ** Can hang your machine, esp prior to 2.4.19
31cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *
32cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz * HISTORY
33cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *	07/2001 Ported by Wayne Boyer
34cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *	07/2002 Split from fork07 as a test case to exhaust available pids.
35cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz *
36cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz * RESTRICTIONS
379ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *	Should be run as root to avoid resource limits.$
389ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *	Should not be run with other test programs because it tries to
399ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao *	  use all available pids.
40cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz */
41cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
42cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz#include <stdio.h>
43cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz#include <sys/wait.h>
44cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz#include <errno.h>
45cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz#include <string.h>
46cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz#include "test.h"
4744827e513f60c69b7b16c0fa9b17a4059961f10aCyril Hrubis#include "safe_macros.h"
48cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
49cdae3fc0101b7926fc68d43b9e242bc05f457858nstrazchar *TCID = "fork12";
50cdae3fc0101b7926fc68d43b9e242bc05f457858nstrazint TST_TOTAL = 1;
51cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
529ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gaostatic void setup(void);
539ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gaostatic void cleanup(void);
549ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gaostatic void fork12_sigs(int signum);
55cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
5656207cec7732e09c216c751c0b5f88a242bacae6subrata_modakint main(int ac, char **av)
57cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz{
58cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	int forks, pid1, fork_errno, waitstatus;
5944bbe6b16ea0f17729a24a0782559576d645514esubrata_modak	int ret, status;
609ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao	int lc;
61cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
62d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis	tst_parse_opts(ac, av, NULL, NULL);
63cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
64cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	setup();
65cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
66cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	for (lc = 0; TEST_LOOPING(lc); lc++) {
67d59a659cd639ca2780b00049d102acd2a783d585Caspar Zhang		tst_count = 0;
68cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
69cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		tst_resm(TINFO, "Forking as many kids as possible");
70cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		forks = 0;
71cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		while ((pid1 = fork()) != -1) {
7256207cec7732e09c216c751c0b5f88a242bacae6subrata_modak			if (pid1 == 0) {	/* child */
7356207cec7732e09c216c751c0b5f88a242bacae6subrata_modak				pause();
7456207cec7732e09c216c751c0b5f88a242bacae6subrata_modak				exit(0);
7556207cec7732e09c216c751c0b5f88a242bacae6subrata_modak			}
7656207cec7732e09c216c751c0b5f88a242bacae6subrata_modak			forks++;
7744827e513f60c69b7b16c0fa9b17a4059961f10aCyril Hrubis			ret = SAFE_WAITPID(cleanup, -1, &status, WNOHANG);
7856207cec7732e09c216c751c0b5f88a242bacae6subrata_modak			if (ret > 0) {
7956207cec7732e09c216c751c0b5f88a242bacae6subrata_modak				/* a child may be killed by OOM killer */
8056207cec7732e09c216c751c0b5f88a242bacae6subrata_modak				if (WTERMSIG(status) == SIGKILL)
8156207cec7732e09c216c751c0b5f88a242bacae6subrata_modak					break;
8256207cec7732e09c216c751c0b5f88a242bacae6subrata_modak				tst_brkm(TBROK, cleanup,
8356207cec7732e09c216c751c0b5f88a242bacae6subrata_modak					 "child exit with error code %d or signal %d",
8456207cec7732e09c216c751c0b5f88a242bacae6subrata_modak					 WEXITSTATUS(status), WTERMSIG(status));
8556207cec7732e09c216c751c0b5f88a242bacae6subrata_modak			}
86cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		}
87cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		fork_errno = errno;
88cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
89cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		/* parent */
90cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		tst_resm(TINFO, "Number of processes forked is %d", forks);
91cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		tst_resm(TPASS, "fork() eventually failed with %d: %s",
9256207cec7732e09c216c751c0b5f88a242bacae6subrata_modak			 fork_errno, strerror(fork_errno));
93cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		/* collect our kids */
949ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao		/*
959ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao		 * Introducing a sleep(3) to make sure all children are
969ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao		 * at pause() when SIGQUIT is sent to them
979ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao		 */
989ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao		sleep(3);
99cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz		kill(0, SIGQUIT);
100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		while (wait(&waitstatus) > 0) ;
101cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
102cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	}
103cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
1049ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao	cleanup();
1057d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper	tst_exit();
106cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz}
107cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
108c57fba5535abf457e33dd7a986b6c512d95cdef6Mike Frysingerstatic void setup(void)
109cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz{
110cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	tst_sig(FORK, fork12_sigs, cleanup);
111cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	TEST_PAUSE;
112cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz}
113cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
114c57fba5535abf457e33dd7a986b6c512d95cdef6Mike Frysingerstatic void cleanup(void)
115cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz{
116cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	int waitstatus;
117cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
118cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	/* collect our kids */
119cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz	kill(0, SIGQUIT);
120354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (wait(&waitstatus) > 0) ;
121cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz}
122cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz
1239ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gaostatic void fork12_sigs(int signum)
124cdae3fc0101b7926fc68d43b9e242bc05f457858nstraz{
12556207cec7732e09c216c751c0b5f88a242bacae6subrata_modak	if (signum == SIGQUIT) {
12656207cec7732e09c216c751c0b5f88a242bacae6subrata_modak		/* Children will continue, parent will ignore */
1279ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao	} else {
1285262667a4c30c82180d439bae4d7787f45281289Garrett Cooper		tst_brkm(TBROK, cleanup,
1299ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao			 "Unexpected signal %d received.", signum);
1309ae5cba56980526c3fd3078f7301cd4dd19ca88aWanlong Gao	}
1315262667a4c30c82180d439bae4d7787f45281289Garrett Cooper}
132