blob: 509daf9822cacadd5d322d3f8fffc9761d166c11 [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 * waitpid05.c
23 *
24 * DESCRIPTION
25 * Check that when a child kills itself with a kill statement after
26 * determining its process id by using getpid, the parent receives a
27 * correct report of the cause of its death. This also indirectly
28 * checks that getpid returns the correct process id.
29 *
30 * ALGORITHM
31 * For signals 1 - 15: fork a child that determines it's own process
32 * id, then sends the signal to itself. The parent waits to see if the
33 * demise of the child results in the signal number being returned to
34 * the parent.
35 *
36 * USAGE: <for command-line>
37 * waitpid05 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
38 * where, -c n : Run n copies concurrently.
39 * -e : Turn on errno logging.
40 * -i n : Execute test n times.
41 * -I x : Execute test for x seconds.
42 * -P x : Pause for x seconds between iterations.
43 * -t : Turn on syscall timing.
44 *
45 * History
46 * 07/2001 John George
47 * -Ported
robbiew4644c7e2002-04-26 14:33:32 +000048 * 04/2002 wjhuie sigset cleanups
plars865695b2001-08-27 22:15:12 +000049 *
50 * Restrictions
51 * None
52 */
53
54#include <sys/file.h>
55#include <sys/signal.h>
56#include <sys/types.h>
57#include <sys/wait.h>
plars4814b682001-10-25 15:32:43 +000058#include <sys/time.h>
59#include <sys/resource.h>
60#include <unistd.h>
plars865695b2001-08-27 22:15:12 +000061#include <errno.h>
Garrett Coopere8530df2010-12-21 11:37:57 -080062#include "test.h"
plars865695b2001-08-27 22:15:12 +000063
Wanlong Gao2c58f602012-11-20 10:32:33 +080064static void do_child(int);
65static void setup(void);
66static void cleanup(void);
plars865695b2001-08-27 22:15:12 +000067
68char *TCID = "waitpid05";
69int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000070
robbiewd34d5812005-07-11 22:28:09 +000071#ifdef UCLINUX
Wanlong Gao2c58f602012-11-20 10:32:33 +080072static void do_child_uclinux(void);
robbiewd34d5812005-07-11 22:28:09 +000073static int sig_uclinux;
74#endif
75
plars74948ad2002-11-14 16:16:14 +000076int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000077{
78 int pid, npid, sig, nsig;
79 int exno, nexno, status;
Cyril Hrubis89af32a2012-10-24 16:39:11 +020080 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020081 const char *msg;
plars865695b2001-08-27 22:15:12 +000082
Wanlong Gao2c58f602012-11-20 10:32:33 +080083 msg = parse_opts(ac, av, NULL, NULL);
84 if (msg != NULL)
plars865695b2001-08-27 22:15:12 +000085 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -080086
robbiewd34d5812005-07-11 22:28:09 +000087#ifdef UCLINUX
88 maybe_run_child(&do_child_uclinux, "d", &sig_uclinux);
89#endif
90
plars865695b2001-08-27 22:15:12 +000091 setup();
92
93 /* check for looping state if -i option is given */
94 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +080095 /* reset tst_count in case we are looping */
96 tst_count = 0;
subrata_modak56207ce2009-03-23 13:35:39 +000097
plars865695b2001-08-27 22:15:12 +000098 /*
99 * Set SIGTERM to SIG_DFL as test driver sets up to ignore
100 * SIGTERM
subrata_modak56207ce2009-03-23 13:35:39 +0000101 */
robbiew4644c7e2002-04-26 14:33:32 +0000102 if (signal(SIGTERM, SIG_DFL) == SIG_ERR) {
plars865695b2001-08-27 22:15:12 +0000103 tst_resm(TFAIL, "Sigset SIGTERM failed, errno = %d",
104 errno);
Garrett Cooper2c282152010-12-16 00:55:50 -0800105
plars865695b2001-08-27 22:15:12 +0000106 }
107
108 exno = 1;
109 for (sig = 1; sig <= 15; sig++) {
Wanlong Gao2c58f602012-11-20 10:32:33 +0800110 if (sig == SIGUSR1 || sig == SIGUSR2 || sig == SIGBUS)
plars865695b2001-08-27 22:15:12 +0000111 continue;
Wanlong Gao2c58f602012-11-20 10:32:33 +0800112
subrata_modak56207ce2009-03-23 13:35:39 +0000113 /*Initialize signal to its default action */
114 signal(sig, SIG_DFL);
robbiewd34d5812005-07-11 22:28:09 +0000115 pid = FORK_OR_VFORK();
plars865695b2001-08-27 22:15:12 +0000116
117 if (pid == 0) {
robbiewd34d5812005-07-11 22:28:09 +0000118#ifdef UCLINUX
119 self_exec(av[0], "d", sig);
120 /* No fork() error check is done so don't */
121 /* do an error check here */
122#else
123 do_child(sig);
124#endif
plars865695b2001-08-27 22:15:12 +0000125 } else {
126 errno = 0;
127 while (((npid = waitpid(pid, &status, 0)) !=
128 -1) || (errno == EINTR)) {
Wanlong Gao2c58f602012-11-20 10:32:33 +0800129 if (errno == EINTR)
plars865695b2001-08-27 22:15:12 +0000130 continue;
Wanlong Gao2c58f602012-11-20 10:32:33 +0800131
plars865695b2001-08-27 22:15:12 +0000132 if (npid != pid) {
133 tst_resm(TFAIL, "waitpid "
134 "error: unexpected "
135 "pid returned");
136 } else {
137 tst_resm(TPASS, "received "
subrata_modak56207ce2009-03-23 13:35:39 +0000138 "expected pid.");
plars865695b2001-08-27 22:15:12 +0000139 }
140
141 nsig = status % 256;
142
143 /*
144 * to check if the core dump bit has
145 * been set, bit #7
146 */
147 if (nsig >= 128) {
148 nsig -= 128;
149 if ((sig == 1) || (sig == 2) ||
Wanlong Gao2c58f602012-11-20 10:32:33 +0800150 (sig == 9) || (sig == 13) ||
plars865695b2001-08-27 22:15:12 +0000151 (sig == 14) ||
152 (sig == 15)) {
153 tst_resm(TFAIL,
154 "signal "
155 "error : "
156 "core dump "
157 "bit set for"
158 " exception "
159 "number %d",
160 sig);
161 }
162 } else if ((sig == 3) || (sig == 4) ||
163 (sig == 5) || (sig == 6) ||
164 (sig == 8) || (sig == 11)) {
165 tst_resm(TFAIL,
166 "signal error: "
167 "core dump bit not "
168 "set for exception "
169 "number %d", sig);
170 }
171
172 /*
173 * nsig is the signal number returned
174 * by waitpid
175 */
176 if (nsig != sig) {
177 tst_resm(TFAIL, "waitpid "
178 "error: unexpected "
179 "signal returned");
180 tst_resm(TINFO, "got signal "
181 "%d, expected "
182 "%d", nsig, sig);
183 }
184
185 /*
186 * nexno is the exit number returned
187 * by waitpid
188 */
189 nexno = status / 256;
190 if (nexno != 0) {
191 tst_resm(TFAIL, "signal "
192 "error: unexpected "
193 "exit number "
194 "returned");
195 } else {
196 tst_resm(TPASS, "received "
subrata_modak56207ce2009-03-23 13:35:39 +0000197 "expected exit number.");
plars865695b2001-08-27 22:15:12 +0000198 }
199 }
200 }
201 }
202
Wanlong Gao2c58f602012-11-20 10:32:33 +0800203 if (access("core", F_OK) == 0)
plars865695b2001-08-27 22:15:12 +0000204 unlink("core");
plars865695b2001-08-27 22:15:12 +0000205 }
Wanlong Gao2c58f602012-11-20 10:32:33 +0800206
plars865695b2001-08-27 22:15:12 +0000207 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800208 tst_exit();
plars865695b2001-08-27 22:15:12 +0000209}
210
Wanlong Gao2c58f602012-11-20 10:32:33 +0800211static void do_child(int sig)
robbiewd34d5812005-07-11 22:28:09 +0000212{
213 int exno = 1;
214 int pid = getpid();
215
216 if (kill(pid, sig) == -1) {
217 tst_resm(TFAIL, "kill error: kill unsuccessful");
218 exit(exno);
219 }
220}
221
222#ifdef UCLINUX
223/*
224 * do_child_uclinux()
225 * run do_child with the appropriate sig variable
226 */
Wanlong Gao2c58f602012-11-20 10:32:33 +0800227static void do_child_uclinux(void)
robbiewd34d5812005-07-11 22:28:09 +0000228{
229 do_child(sig_uclinux);
subrata_modak4bb656a2009-02-26 12:02:09 +0000230}
robbiewd34d5812005-07-11 22:28:09 +0000231#endif
232
Wanlong Gao2c58f602012-11-20 10:32:33 +0800233static void setup(void)
plars865695b2001-08-27 22:15:12 +0000234{
plars4814b682001-10-25 15:32:43 +0000235 struct rlimit newlimit;
236
plars865695b2001-08-27 22:15:12 +0000237 TEST_PAUSE;
238
plars865695b2001-08-27 22:15:12 +0000239 tst_tmpdir();
plars4814b682001-10-25 15:32:43 +0000240
vapierd17884d2006-05-26 05:47:00 +0000241 newlimit.rlim_max = newlimit.rlim_cur = RLIM_INFINITY;
242 if (setrlimit(RLIMIT_CORE, &newlimit) != 0)
subrata_modak56207ce2009-03-23 13:35:39 +0000243 tst_resm(TWARN,
244 "setrlimit(RLIMIT_CORE,RLIM_INFINITY) failed; this may cause some false core-dump test failures");
plars865695b2001-08-27 22:15:12 +0000245}
246
Wanlong Gao2c58f602012-11-20 10:32:33 +0800247static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000248{
plars865695b2001-08-27 22:15:12 +0000249 tst_rmdir();
Wanlong Gao2c58f602012-11-20 10:32:33 +0800250}