blob: 573217105d0da2f2ae563f475c445643caea4ecf [file] [log] [blame]
nstrazcdae3fc2002-07-19 15:59:19 +00001/*
nstrazcdae3fc2002-07-19 15:59:19 +00002 * 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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Wanlong Gao9ae5cba2012-09-18 17:14:01 +080017 *
18 *
nstrazcdae3fc2002-07-19 15:59:19 +000019 * NAME
Wanlong Gao9ae5cba2012-09-18 17:14:01 +080020 * fork12.c
nstrazcdae3fc2002-07-19 15:59:19 +000021 *
22 * DESCRIPTION
23 * Check that all children inherit parent's file descriptor
24 *
25 * ALGORITHM
Wanlong Gao9ae5cba2012-09-18 17:14:01 +080026 * Parent forks processes until -1 is returned.$
27 *
nstrazcdae3fc2002-07-19 15:59:19 +000028 * USAGE
Wanlong Gao9ae5cba2012-09-18 17:14:01 +080029 * fork12
30 * ** CAUTION ** Can hang your machine, esp prior to 2.4.19
nstrazcdae3fc2002-07-19 15:59:19 +000031 *
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
Wanlong Gao9ae5cba2012-09-18 17:14:01 +080037 * 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.
nstrazcdae3fc2002-07-19 15:59:19 +000040 */
41
42#include <stdio.h>
43#include <sys/wait.h>
44#include <errno.h>
45#include <string.h>
46#include "test.h"
nstrazcdae3fc2002-07-19 15:59:19 +000047
48char *TCID = "fork12";
49int TST_TOTAL = 1;
nstrazcdae3fc2002-07-19 15:59:19 +000050
Wanlong Gao9ae5cba2012-09-18 17:14:01 +080051static void setup(void);
52static void cleanup(void);
53static void fork12_sigs(int signum);
nstrazcdae3fc2002-07-19 15:59:19 +000054
subrata_modak56207ce2009-03-23 13:35:39 +000055int main(int ac, char **av)
nstrazcdae3fc2002-07-19 15:59:19 +000056{
57 int forks, pid1, fork_errno, waitstatus;
subrata_modak44bbe6b2008-06-08 13:34:16 +000058 int ret, status;
Wanlong Gao9ae5cba2012-09-18 17:14:01 +080059 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020060 const char *msg;
nstrazcdae3fc2002-07-19 15:59:19 +000061
Wanlong Gao9ae5cba2012-09-18 17:14:01 +080062 msg = parse_opts(ac, av, NULL, NULL);
63 if (msg != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080064 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
nstrazcdae3fc2002-07-19 15:59:19 +000065
nstrazcdae3fc2002-07-19 15:59:19 +000066 setup();
67
nstrazcdae3fc2002-07-19 15:59:19 +000068 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080069 tst_count = 0;
nstrazcdae3fc2002-07-19 15:59:19 +000070
71 tst_resm(TINFO, "Forking as many kids as possible");
72 forks = 0;
73 while ((pid1 = fork()) != -1) {
subrata_modak56207ce2009-03-23 13:35:39 +000074 if (pid1 == 0) { /* child */
75 pause();
76 exit(0);
77 }
78 forks++;
79 ret = waitpid(-1, &status, WNOHANG);
80 if (ret < 0)
81 tst_brkm(TBROK, cleanup,
82 "waitpid failed %d: %s\n", errno,
83 strerror(errno));
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 }
nstrazcdae3fc2002-07-19 15:59:19 +000092 }
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",
subrata_modak56207ce2009-03-23 13:35:39 +000098 fork_errno, strerror(fork_errno));
nstrazcdae3fc2002-07-19 15:59:19 +000099 /* collect our kids */
Wanlong Gao9ae5cba2012-09-18 17:14:01 +0800100 /*
101 * Introducing a sleep(3) to make sure all children are
102 * at pause() when SIGQUIT is sent to them
103 */
104 sleep(3);
nstrazcdae3fc2002-07-19 15:59:19 +0000105 kill(0, SIGQUIT);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800106 while (wait(&waitstatus) > 0) ;
nstrazcdae3fc2002-07-19 15:59:19 +0000107
108 }
nstrazcdae3fc2002-07-19 15:59:19 +0000109
Wanlong Gao9ae5cba2012-09-18 17:14:01 +0800110 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800111 tst_exit();
nstrazcdae3fc2002-07-19 15:59:19 +0000112}
113
Mike Frysingerc57fba52014-04-09 18:56:30 -0400114static void setup(void)
nstrazcdae3fc2002-07-19 15:59:19 +0000115{
nstrazcdae3fc2002-07-19 15:59:19 +0000116 tst_sig(FORK, fork12_sigs, cleanup);
nstrazcdae3fc2002-07-19 15:59:19 +0000117 TEST_PAUSE;
118}
119
Mike Frysingerc57fba52014-04-09 18:56:30 -0400120static void cleanup(void)
nstrazcdae3fc2002-07-19 15:59:19 +0000121{
122 int waitstatus;
123
124 /* collect our kids */
125 kill(0, SIGQUIT);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800126 while (wait(&waitstatus) > 0) ;
nstrazcdae3fc2002-07-19 15:59:19 +0000127}
128
Wanlong Gao9ae5cba2012-09-18 17:14:01 +0800129static void fork12_sigs(int signum)
nstrazcdae3fc2002-07-19 15:59:19 +0000130{
subrata_modak56207ce2009-03-23 13:35:39 +0000131 if (signum == SIGQUIT) {
132 /* Children will continue, parent will ignore */
Wanlong Gao9ae5cba2012-09-18 17:14:01 +0800133 } else {
Garrett Cooper52626672010-12-20 15:03:21 -0800134 tst_brkm(TBROK, cleanup,
Wanlong Gao9ae5cba2012-09-18 17:14:01 +0800135 "Unexpected signal %d received.", signum);
136 }
Garrett Cooper52626672010-12-20 15:03:21 -0800137}