fork12.c revision d59a659cd639ca2780b00049d102acd2a783d585
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 "usctest.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 char *msg; 62 63 msg = parse_opts(ac, av, NULL, NULL); 64 if (msg != NULL) 65 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); 66 67 setup(); 68 69 for (lc = 0; TEST_LOOPING(lc); lc++) { 70 tst_count = 0; 71 72 tst_resm(TINFO, "Forking as many kids as possible"); 73 forks = 0; 74 while ((pid1 = fork()) != -1) { 75 if (pid1 == 0) { /* child */ 76 pause(); 77 exit(0); 78 } 79 forks++; 80 ret = waitpid(-1, &status, WNOHANG); 81 if (ret < 0) 82 tst_brkm(TBROK, cleanup, 83 "waitpid failed %d: %s\n", errno, 84 strerror(errno)); 85 if (ret > 0) { 86 /* a child may be killed by OOM killer */ 87 if (WTERMSIG(status) == SIGKILL) 88 break; 89 tst_brkm(TBROK, cleanup, 90 "child exit with error code %d or signal %d", 91 WEXITSTATUS(status), WTERMSIG(status)); 92 } 93 } 94 fork_errno = errno; 95 96 /* parent */ 97 tst_resm(TINFO, "Number of processes forked is %d", forks); 98 tst_resm(TPASS, "fork() eventually failed with %d: %s", 99 fork_errno, strerror(fork_errno)); 100 /* collect our kids */ 101 /* 102 * Introducing a sleep(3) to make sure all children are 103 * at pause() when SIGQUIT is sent to them 104 */ 105 sleep(3); 106 kill(0, SIGQUIT); 107 while (wait(&waitstatus) > 0) ; 108 109 } 110 111 cleanup(); 112 tst_exit(); 113} 114 115static void setup() 116{ 117 tst_sig(FORK, fork12_sigs, cleanup); 118 TEST_PAUSE; 119} 120 121static void cleanup() 122{ 123 int waitstatus; 124 125 /* collect our kids */ 126 kill(0, SIGQUIT); 127 while (wait(&waitstatus) > 0) ; 128 TEST_CLEANUP; 129} 130 131static void fork12_sigs(int signum) 132{ 133 if (signum == SIGQUIT) { 134 /* Children will continue, parent will ignore */ 135 } else { 136 tst_brkm(TBROK, cleanup, 137 "Unexpected signal %d received.", signum); 138 } 139} 140