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 49char *TCID = "fork12"; 50int TST_TOTAL = 1; 51 52static void setup(void); 53static void cleanup(void); 54static void fork12_sigs(int signum); 55 56int 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 114static void setup(void) 115{ 116 tst_sig(FORK, fork12_sigs, cleanup); 117 TEST_PAUSE; 118} 119 120static void cleanup(void) 121{ 122 int waitstatus; 123 124 /* collect our kids */ 125 kill(0, SIGQUIT); 126 while (wait(&waitstatus) > 0) ; 127} 128 129static 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