void reset_counter(int sig) { checklist_reset(0xFF); child_signal_counter = 0; if (debug_flag >= 3) printf("%d: reset_counter\n", mypid); }
/*************************************************************** * setup() - performs all ONE TIME setup for this test. ***************************************************************/ void setup() { struct sigaction sa; int i; /* You will want to enable some signal handling so you can capture * unexpected signals like SIGSEGV. */ tst_sig(FORK, DEF_HANDLER, cleanup); /* Pause if that option was specified */ /* One cavet that hasn't been fixed yet. TEST_PAUSE contains the code to * fork the test with the -c option. You want to make sure you do this * before you create your temporary directory. */ TEST_PAUSE; mypid = getpid(); sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (debug_flag >= 1) printf("%d: setting SIGTRAP -> SIG_DFL\n", mypid); k_sigaction(SIGTRAP, &sa, 0); if (debug_flag >= 1) printf("%d: setting SIGCONT -> SIG_DFL\n", mypid); k_sigaction(SIGCONT, &sa, 0); sa.sa_handler = set_create_procs; if (debug_flag >= 4) printf("%d: setting SIGALRM -> set_create_procs\n", mypid); k_sigaction(SIGALRM, &sa, 0); sa.sa_handler = NULL; sa.sa_sigaction = ack_ready; sa.sa_flags = SA_SIGINFO; if (debug_flag >= 1) printf("%d: setting SIGUSR1 -> ack_ready\n", mypid); k_sigaction(SIGUSR1, &sa, 0); fork_pgrps(num_pgrps); /* wait for all pgrps to report in */ if (debug_flag) printf("Master: %d\n", mypid); while (pgrps_ready < num_pgrps) { if (debug_flag >= 3) printf("%d: Master pausing for Managers to check in (%d/%d)\n", mypid, pgrps_ready, num_pgrps); /* * We might recieve the signal from the (last manager) before * we issue a pause. In that case we might hang even if we have * all the managers reported in. So set an alarm so that we can * wake up. */ alarm(1); pause(); } checklist_reset(0x03); if (debug_flag) { printf("Managers: \n"); for (i = 0; i < num_pgrps; i++) { printf("%d ", child_checklist[i].pid); } printf("\n"); } /* set up my signal processing */ /* continue on ALRM */ sa.sa_handler = wakeup; if (debug_flag >= 4) printf("%d: setting SIGALRM -> wakeup\n", mypid); k_sigaction(SIGALRM, &sa, 0); /* reply to child on USR2 */ sa.sa_handler = NULL; sa.sa_sigaction = ack_done; sa.sa_flags = SA_SIGINFO; if (debug_flag >= 1) printf("%d: setting SIGUSR2 -> ack_done\n", mypid); k_sigaction(SIGUSR2, &sa, 0); }
/*********************************************************************** * Main ***********************************************************************/ int main(int ac, char **av) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ int cnt; Tst_nobuf=1; /*************************************************************** * parse standard options ***************************************************************/ /* start off by parsing the command line options. We provide a function * that understands many common options to control looping. If you are not * adding any new options, pass NULL in place of options and &help. */ if ((msg = parse_opts(ac, av, options, &help))) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); tst_exit(); } if (nflag) { if (sscanf(narg, "%i", &num_procs) != 1 ) { tst_brkm(TBROK, NULL, "-n option arg is not a number"); tst_exit(); } } if (gflag) { if (sscanf(garg, "%i", &num_pgrps) != 1 ) { tst_brkm(TBROK, NULL, "-g option arg is not a number"); tst_exit(); } } if (dflag) { if (sscanf(darg, "%i", &debug_flag) != 1 ) { tst_brkm(TBROK, NULL, "-d option arg is not a number"); tst_exit(); } } /*************************************************************** * perform global setup for test ***************************************************************/ /* Next you should run a setup routine to make sure your environment is * sane. */ setup(); /* set the expected errnos... */ TEST_EXP_ENOS(exp_enos); /*************************************************************** * check looping state ***************************************************************/ /* TEST_LOOPING() is a macro that will make sure the test continues * looping according to the standard command line args. */ for (lc=0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping. */ Tst_count=0; child_signal_counter = 0; pgrps_ready = 0; checklist_reset(0x03); /* send SIGUSR1 to each pgroup */ for (cnt = 0; cnt < child_checklist_total; ++cnt) { if (debug_flag >= 2) printf("%d: test_loop, SIGUSR1 -> %d\n", mypid, -child_checklist[cnt].pid); kill(-child_checklist[cnt].pid, SIGUSR1); } /* wait for the managers to signal they are done */ while (child_signal_counter < num_pgrps) { alarm(1); if (debug_flag >= 2) printf("%d: Master pausing for done (%d/%d)\n", mypid, child_signal_counter, num_pgrps); pause(); } tst_resm(TPASS, "All %d pgrps received their signals", child_signal_counter); /* Here we clean up after the test case so we can do another iteration. */ } /* End for TEST_LOOPING */ /*************************************************************** * cleanup and exit ***************************************************************/ cleanup(); return 0; } /* End main */
int main(int ac, char **av) { int lc; char *msg; int cnt; if ((msg = parse_opts(ac, av, options, &help))) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } if (nflag) { if (sscanf(narg, "%i", &num_procs) != 1) { tst_brkm(TBROK, NULL, "-n option arg is not a number"); } } if (gflag) { if (sscanf(garg, "%i", &num_pgrps) != 1) { tst_brkm(TBROK, NULL, "-g option arg is not a number"); } } if (dflag) { if (sscanf(darg, "%i", &debug_flag) != 1) { tst_brkm(TBROK, NULL, "-d option arg is not a number"); } } setup(); TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { Tst_count = 0; child_signal_counter = 0; pgrps_ready = 0; checklist_reset(0x03); /* send SIGUSR1 to each pgroup */ for (cnt = 0; cnt < child_checklist_total; ++cnt) { if (debug_flag >= 2) printf("%d: test_loop, SIGUSR1 -> %d\n", mypid, -child_checklist[cnt].pid); kill(-child_checklist[cnt].pid, SIGUSR1); } /* wait for the managers to signal they are done */ while (child_signal_counter < num_pgrps) { alarm(1); if (debug_flag >= 2) printf("%d: Master pausing for done (%d/%d)\n", mypid, child_signal_counter, num_pgrps); pause(); } tst_resm(TPASS, "All %d pgrps received their signals", child_signal_counter); } cleanup(); tst_exit(); }