blob: d094d2641253ebfc12fb107c369574951242eef7 [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/*
nstrazfa31d552002-05-14 16:50:06 +000021 * Test Name: pause03
plars865695b2001-08-27 22:15:12 +000022 *
23 * Test Description:
subrata_modak4bb656a2009-02-26 12:02:09 +000024 * Verify that a process is no longer accessible on receipt of SIGKILL
plars865695b2001-08-27 22:15:12 +000025 * signal after being suspended by pause().
26 *
27 * Expected Result:
28 * pause() does not return due to receipt of SIGKILL signal and specified
29 * process should be terminated.
30 *
31 * Algorithm:
32 * Setup:
33 * Setup signal handling.
34 * Pause for SIGUSR1 if option specified.
35 *
36 * Test:
37 * Loop if the proper options are given.
38 * Execute system call
39 * Check return code, if system call failed (return=-1)
subrata_modak56207ce2009-03-23 13:35:39 +000040 * Log the errno and Issue a FAIL message.
plars865695b2001-08-27 22:15:12 +000041 * Otherwise,
subrata_modak56207ce2009-03-23 13:35:39 +000042 * Verify the Functionality of system call
plars865695b2001-08-27 22:15:12 +000043 * if successful,
subrata_modak56207ce2009-03-23 13:35:39 +000044 * Issue Functionality-Pass message.
plars865695b2001-08-27 22:15:12 +000045 * Otherwise,
46 * Issue Functionality-Fail message.
47 * Cleanup:
48 * Print errno log and/or timing stats if options given
49 *
50 * Usage: <for command-line>
nstrazfa31d552002-05-14 16:50:06 +000051 * pause03 [-c n] [-i n] [-I x] [-P x] [-t]
plars865695b2001-08-27 22:15:12 +000052 * where, -c n : Run n copies concurrently.
53 * -i n : Execute test n times.
54 * -I x : Execute test for x seconds.
55 * -P x : Pause for x seconds between iterations.
56 * -t : Turn on syscall timing.
57 *
58 * HISTORY
59 * 07/2001 Ported by Wayne Boyer
60 *
61 * RESTRICTIONS:
62 * None.
63 *
64 */
65#include <unistd.h>
66#include <errno.h>
67#include <fcntl.h>
68#include <wait.h>
69
70#include "test.h"
plars865695b2001-08-27 22:15:12 +000071
72int cflag; /* flag to indicate child process status */
73pid_t cpid; /* child process id */
74
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020075char *TCID = "pause03";
76int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000077
robbiewd34d5812005-07-11 22:28:09 +000078void do_child(); /* Function to run in child process */
plars865695b2001-08-27 22:15:12 +000079void setup(); /* Main setup function of test */
80void cleanup(); /* cleanup function for the test */
81void sig_handle(int sig); /* signal handler for SIGCLD */
82
subrata_modak56207ce2009-03-23 13:35:39 +000083int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000084{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020085 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020086 const char *msg;
plars865695b2001-08-27 22:15:12 +000087 int status; /* child process exit status */
Cyril Hrubis89af32a2012-10-24 16:39:11 +020088 int ret_val;
subrata_modak56207ce2009-03-23 13:35:39 +000089
Garrett Coopera9e49f12010-12-16 10:54:03 -080090 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080091 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiewd34d5812005-07-11 22:28:09 +000092#ifdef UCLINUX
93 maybe_run_child(&do_child, "");
94#endif
95
plars865695b2001-08-27 22:15:12 +000096 setup();
97
plars865695b2001-08-27 22:15:12 +000098 for (lc = 0; TEST_LOOPING(lc); lc++) {
99
Caspar Zhangd59a6592013-03-07 14:59:12 +0800100 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000101
102 /* Creat a new process using fork() */
vapierfed9da32006-02-19 09:25:08 +0000103 if ((cpid = FORK_OR_VFORK()) == -1) {
plars865695b2001-08-27 22:15:12 +0000104 tst_brkm(TBROK, cleanup, "fork() failed");
105 }
106
subrata_modak56207ce2009-03-23 13:35:39 +0000107 if (cpid == 0) { /* Child process */
robbiewd34d5812005-07-11 22:28:09 +0000108#ifdef UCLINUX
109 if (self_exec(av[0], "") < 0) {
110 tst_brkm(TBROK, cleanup, "self_exec failed");
111 }
112#else
113 do_child();
114#endif
plars865695b2001-08-27 22:15:12 +0000115 }
116
117 /* Parent process */
118 /* sleep to ensure the child executes */
119 sleep(1);
120
121 /* Check for the value of cflag */
122 if (cflag == 1) {
123 /*
124 * Indicates that child terminated
125 * before receipt of SIGKILL signal.
126 */
127 tst_brkm(TFAIL, cleanup,
128 "Child exited before SIGKILL signal");
129 }
130
131 /* Send the SIGKILL signal now */
132 kill(cpid, SIGKILL);
133
134 /* sleep to ensure the signal sent is effected */
135 sleep(1);
136
137 /* Verify again the value of cflag */
138 if (cflag == 0) {
139 /* Child still exists */
140 tst_resm(TFAIL, "Child still exists, "
141 "pause() still active");
142 cleanup();
143 }
144
145 ret_val = wait(&status);
146
147 /*
148 * Verify that wait returned after child process termination
149 * due to receipt of SIGKILL signal.
150 */
subrata_modak56207ce2009-03-23 13:35:39 +0000151 if (WTERMSIG(status) == SIGKILL) {
plars865695b2001-08-27 22:15:12 +0000152 ret_val = wait(&status);
153 if ((ret_val == -1) && (errno == ECHILD)) {
154 /*
155 * Child is no longer accessible and pause()
156 * functionality is successful.
157 */
158 tst_resm(TPASS, "Functionality of "
159 "pause() is correct");
160 } else {
161 tst_resm(TFAIL, "wait() failed due to "
vapier356d38a2009-08-28 13:36:21 +0000162 "unkown reason, ret_val=%d, "
plars865695b2001-08-27 22:15:12 +0000163 "errno=%d", ret_val, errno);
164 }
165 } else {
166 tst_resm(TFAIL, "Child terminated not due to "
167 "SIGKILL, errno = %d", errno);
168 }
169
170 /* reset cflag in case we are looping */
171 cflag = 0;
172
Garrett Cooper2c282152010-12-16 00:55:50 -0800173 }
plars865695b2001-08-27 22:15:12 +0000174
plars865695b2001-08-27 22:15:12 +0000175 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800176 tst_exit();
plars865695b2001-08-27 22:15:12 +0000177
Garrett Cooper2c282152010-12-16 00:55:50 -0800178}
plars865695b2001-08-27 22:15:12 +0000179
180/*
robbiewd34d5812005-07-11 22:28:09 +0000181 * do_child()
182 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400183void do_child(void)
robbiewd34d5812005-07-11 22:28:09 +0000184{
185 /* Suspend the child using pause() */
186 TEST(pause());
subrata_modakbdbaec52009-02-26 12:14:51 +0000187
robbiewd34d5812005-07-11 22:28:09 +0000188 /* print the message if pause() returned */
189 tst_resm(TFAIL, "Unexpected return from pause()");
190 /* Loop infinitely */
subrata_modak56207ce2009-03-23 13:35:39 +0000191 while (1) ;
robbiewd34d5812005-07-11 22:28:09 +0000192}
193
194/*
plars865695b2001-08-27 22:15:12 +0000195 * setup() - performs all ONE TIME setup for this test.
subrata_modak56207ce2009-03-23 13:35:39 +0000196 * Setup signal handler to catch SIGCLD signal.
plars865695b2001-08-27 22:15:12 +0000197 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400198void setup(void)
plars865695b2001-08-27 22:15:12 +0000199{
Garrett Cooper2c282152010-12-16 00:55:50 -0800200
plars865695b2001-08-27 22:15:12 +0000201 tst_sig(FORK, DEF_HANDLER, cleanup);
202
plars865695b2001-08-27 22:15:12 +0000203 TEST_PAUSE;
204
205 /* Initialise cflag */
206 cflag = 0;
207
208 /* Catch SIGCLD */
209 signal(SIGCLD, sig_handle);
210}
211
212/*
213 * sig_handle(int sig)
214 * This is the signal handler to handle the SIGCLD signal.
215 * When the child terminates and the parent gets the SIGCLD signal
subrata_modak4bb656a2009-02-26 12:02:09 +0000216 * the handler gets executed and then the cflag variable is set to
plars865695b2001-08-27 22:15:12 +0000217 * indicate the child has terminated.
218 */
subrata_modak56207ce2009-03-23 13:35:39 +0000219void sig_handle(int sig)
plars865695b2001-08-27 22:15:12 +0000220{
221 /* Set the cflag variable */
222 cflag = 1;
223}
224
225/*
226 * cleanup() - performs all ONE TIME cleanup for this test at
227 * completion or premature exit.
228 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400229void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000230{
plars865695b2001-08-27 22:15:12 +0000231
232 /* Cleanup the child if still active */
233 kill(cpid, SIGKILL);
234
Chris Dearmanec6edca2012-10-17 19:54:01 -0700235}