• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (c) International Business Machines  Corp., 2001
3  *
4  *   This program is free software;  you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  *   the GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program;  if not, write to the Free Software
16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  *
19  * NAME
20  *	fork12.c
21  *
22  * DESCRIPTION
23  *	Check that all children inherit parent's file descriptor
24  *
25  * ALGORITHM
26  *	Parent forks processes until -1 is returned.$
27  *
28  * USAGE
29  *	fork12
30  *	** CAUTION ** Can hang your machine, esp prior to 2.4.19
31  *
32  * HISTORY
33  *	07/2001 Ported by Wayne Boyer
34  *	07/2002 Split from fork07 as a test case to exhaust available pids.
35  *
36  * RESTRICTIONS
37  *	Should be run as root to avoid resource limits.$
38  *	Should not be run with other test programs because it tries to
39  *	  use all available pids.
40  */
41 
42 #include <stdio.h>
43 #include <sys/wait.h>
44 #include <errno.h>
45 #include <string.h>
46 #include "test.h"
47 #include "safe_macros.h"
48 
49 char *TCID = "fork12";
50 int TST_TOTAL = 1;
51 
52 static void setup(void);
53 static void cleanup(void);
54 static void fork12_sigs(int signum);
55 
main(int ac,char ** av)56 int main(int ac, char **av)
57 {
58 	int forks, pid1, fork_errno, waitstatus;
59 	int ret, status;
60 	int lc;
61 
62 	tst_parse_opts(ac, av, NULL, NULL);
63 
64 	setup();
65 
66 	for (lc = 0; TEST_LOOPING(lc); lc++) {
67 		tst_count = 0;
68 
69 		tst_resm(TINFO, "Forking as many kids as possible");
70 		forks = 0;
71 		while ((pid1 = fork()) != -1) {
72 			if (pid1 == 0) {	/* child */
73 				/*
74 				 * Taunt the OOM killer so that it doesn't
75 				 * kill system processes
76 				 */
77 				SAFE_FILE_PRINTF(NULL,
78 					"/proc/self/oom_score_adj", "500");
79 				pause();
80 				exit(0);
81 			}
82 			forks++;
83 			ret = SAFE_WAITPID(cleanup, -1, &status, WNOHANG);
84 			if (ret > 0) {
85 				/* a child may be killed by OOM killer */
86 				if (WTERMSIG(status) == SIGKILL)
87 					break;
88 				tst_brkm(TBROK, cleanup,
89 					 "child exit with error code %d or signal %d",
90 					 WEXITSTATUS(status), WTERMSIG(status));
91 			}
92 		}
93 		fork_errno = errno;
94 
95 		/* parent */
96 		tst_resm(TINFO, "Number of processes forked is %d", forks);
97 		tst_resm(TPASS, "fork() eventually failed with %d: %s",
98 			 fork_errno, strerror(fork_errno));
99 		/* collect our kids */
100 		/*
101 		 * Introducing a sleep(3) to make sure all children are
102 		 * at pause() when SIGQUIT is sent to them
103 		 */
104 		sleep(3);
105 		kill(0, SIGQUIT);
106 		while (wait(&waitstatus) > 0) ;
107 
108 	}
109 
110 	cleanup();
111 	tst_exit();
112 }
113 
setup(void)114 static void setup(void)
115 {
116 	tst_sig(FORK, fork12_sigs, cleanup);
117 	TEST_PAUSE;
118 }
119 
cleanup(void)120 static void cleanup(void)
121 {
122 	int waitstatus;
123 
124 	/* collect our kids */
125 	kill(0, SIGQUIT);
126 	while (wait(&waitstatus) > 0) ;
127 }
128 
fork12_sigs(int signum)129 static void fork12_sigs(int signum)
130 {
131 	if (signum == SIGQUIT) {
132 		/* Children will continue, parent will ignore */
133 	} else {
134 		tst_brkm(TBROK, cleanup,
135 			 "Unexpected signal %d received.", signum);
136 	}
137 }
138