blob: 3559156889a446a60bdbae9ff153781e8ac93ee5 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
22 * waitpid03.c
23 *
24 * DESCRIPTION
25 * Check that parent waits unitl specific child has returned.
26 *
27 * ALGORITHM
28 * Parent forks numerous (22 = MAXUPRC - 3) children, and starts waits :
29 * Should only wait for the specific child, a second wait on the same
30 * child should return with -1 and not one of the other zombied
31 * children.
32 *
33 * USAGE: <for command-line>
34 * waitpid03 [-c n] [-i n] [-I x] [-P x] [-t]
35 * where, -c n : Run n copies concurrently.
36 * -i n : Execute test n times.
37 * -I x : Execute test for x seconds.
38 * -P x : Pause for x seconds between iterations.
39 * -t : Turn on syscall timing.
40 *
41 * History
42 * 07/2001 John George
43 * -Ported
robbiew4644c7e2002-04-26 14:33:32 +000044 * 04/2002 wjhuie sigset cleanups
plars865695b2001-08-27 22:15:12 +000045 *
46 * Restrictions
47 * None
48 */
49
plarsb3c1c252003-07-08 18:57:47 +000050#define DEBUG 0
51
plarse24e78e2002-06-10 12:19:25 +000052#include <sys/types.h>
plars865695b2001-08-27 22:15:12 +000053#include <signal.h>
54#include <errno.h>
plarse24e78e2002-06-10 12:19:25 +000055#include <sys/wait.h>
Garrett Coopere8530df2010-12-21 11:37:57 -080056#include "test.h"
plars865695b2001-08-27 22:15:12 +000057
Wanlong Gaod08183c2012-11-20 10:32:33 +080058static void do_child(int);
59static void setup(void);
60static void cleanup(void);
plars865695b2001-08-27 22:15:12 +000061
62char *TCID = "waitpid03";
63int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000064
65#define MAXUPRC 25
66
Wanlong Gaod08183c2012-11-20 10:32:33 +080067static int condition_number;
plars865695b2001-08-27 22:15:12 +000068
robbiewd34d5812005-07-11 22:28:09 +000069#ifdef UCLINUX
Wanlong Gaod08183c2012-11-20 10:32:33 +080070static void do_child_uclinux(void);
robbiewd34d5812005-07-11 22:28:09 +000071static int ikids_uclinux;
72#endif
73
plarse24e78e2002-06-10 12:19:25 +000074int main(int argc, char **argv)
plars865695b2001-08-27 22:15:12 +000075{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020076 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020077 const char *msg;
plars865695b2001-08-27 22:15:12 +000078
79 int status, pid[25], ret;
80
Wanlong Gaod08183c2012-11-20 10:32:33 +080081 msg = parse_opts(argc, argv, NULL, NULL);
82 if (msg != NULL)
plars865695b2001-08-27 22:15:12 +000083 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiewd34d5812005-07-11 22:28:09 +000084#ifdef UCLINUX
85 maybe_run_child(&do_child, "d", &ikids_uclinux);
86#endif
87
plars865695b2001-08-27 22:15:12 +000088 setup();
89
90 /* check for looping state if -i option is given */
91 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080092 /* reset tst_count in case we are looping */
plars865695b2001-08-27 22:15:12 +000093 int ikids = 0;
Caspar Zhangd59a6592013-03-07 14:59:12 +080094 tst_count = 0;
plars865695b2001-08-27 22:15:12 +000095
96 /*
97 * Set SIGTERM to SIG_DFL as test driver sets up to ignore
98 * SIGTERM
99 */
subrata_modak56207ce2009-03-23 13:35:39 +0000100 if ((sig_t) signal(SIGTERM, SIG_DFL) == SIG_ERR) {
robbiew4644c7e2002-04-26 14:33:32 +0000101 tst_resm(TFAIL, "Signal SIGTERM failed, errno = %d",
plars865695b2001-08-27 22:15:12 +0000102 errno);
Garrett Cooper2c282152010-12-16 00:55:50 -0800103
plars865695b2001-08-27 22:15:12 +0000104 }
105
106 while (++ikids < MAXUPRC) {
Wanlong Gaod08183c2012-11-20 10:32:33 +0800107 pid[ikids] = FORK_OR_VFORK();
108 if (pid[ikids] > 0) {
plarsb3c1c252003-07-08 18:57:47 +0000109 if (DEBUG)
110 tst_resm(TINFO, "child # %d", ikids);
plars865695b2001-08-27 22:15:12 +0000111 } else if (pid[ikids] == -1) {
subrata_modak56207ce2009-03-23 13:35:39 +0000112 tst_resm(TFAIL, "cannot open fork #%d", ikids);
plars865695b2001-08-27 22:15:12 +0000113 } else {
robbiewd34d5812005-07-11 22:28:09 +0000114#ifdef UCLINUX
115 if (self_exec(argv[0], "d", ikids) < 0) {
116 tst_resm(TFAIL, "cannot self_exec #%d",
117 ikids);
118 }
119#else
120 do_child(ikids);
121#endif
plars865695b2001-08-27 22:15:12 +0000122 }
123 }
124
125 for (ikids = 1; ikids < MAXUPRC; ikids++) {
plarsb3c1c252003-07-08 18:57:47 +0000126 if (DEBUG)
127 tst_resm(TINFO, "Killing #%d", ikids);
plars865695b2001-08-27 22:15:12 +0000128 kill(pid[ikids], 15);
129 }
130
subrata_modak3976f662008-02-25 09:40:12 +0000131 condition_number = 1;
132
plars865695b2001-08-27 22:15:12 +0000133 /* Wait on one specific child */
plarsb3c1c252003-07-08 18:57:47 +0000134 if (DEBUG)
135 tst_resm(TINFO, "Waiting for child:#%d", MAXUPRC / 2);
plars865695b2001-08-27 22:15:12 +0000136 ret = waitpid(pid[MAXUPRC / 2], &status, 0);
137 if (ret != pid[MAXUPRC / 2]) {
138 tst_resm(TFAIL, "condition %d test failed. "
subrata_modak56207ce2009-03-23 13:35:39 +0000139 "waitpid(%d) returned %d.",
140 condition_number, pid[MAXUPRC / 2], ret);
plars865695b2001-08-27 22:15:12 +0000141 } else {
142 tst_resm(TPASS, "Got correct child PID");
143 }
subrata_modak3976f662008-02-25 09:40:12 +0000144 condition_number++;
plars865695b2001-08-27 22:15:12 +0000145
146 /*
147 * Child has already been waited on, waitpid should return
148 * -1
149 */
150 ret = waitpid(pid[MAXUPRC / 2], &status, 0);
151 if (ret != -1) {
152 tst_resm(TFAIL, "condition %d test failed",
subrata_modak3976f662008-02-25 09:40:12 +0000153 condition_number);
plars865695b2001-08-27 22:15:12 +0000154 } else {
155 tst_resm(TPASS, "Condition %d test passed",
subrata_modak56207ce2009-03-23 13:35:39 +0000156 condition_number);
plars865695b2001-08-27 22:15:12 +0000157 }
subrata_modak3976f662008-02-25 09:40:12 +0000158 condition_number++;
plars865695b2001-08-27 22:15:12 +0000159 }
Wanlong Gaod08183c2012-11-20 10:32:33 +0800160
plars865695b2001-08-27 22:15:12 +0000161 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800162 tst_exit();
plars865695b2001-08-27 22:15:12 +0000163}
164
Wanlong Gaod08183c2012-11-20 10:32:33 +0800165static void do_child(int ikids)
robbiewd34d5812005-07-11 22:28:09 +0000166{
167 if (DEBUG)
168 tst_resm(TINFO, "child:%d", ikids);
169 pause();
170 exit(0);
171}
172
173#ifdef UCLINUX
174/*
175 * do_child_uclinux()
176 * run do_child with the appropriate ikids variable
177 */
Wanlong Gaod08183c2012-11-20 10:32:33 +0800178static void do_child_uclinux(void)
robbiewd34d5812005-07-11 22:28:09 +0000179{
180 do_child(ikids_uclinux);
181}
182#endif
183
Wanlong Gaod08183c2012-11-20 10:32:33 +0800184static void setup(void)
plars865695b2001-08-27 22:15:12 +0000185{
plars865695b2001-08-27 22:15:12 +0000186 TEST_PAUSE;
187}
188
Wanlong Gaod08183c2012-11-20 10:32:33 +0800189static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000190{
Wanlong Gaod08183c2012-11-20 10:32:33 +0800191}