blob: a63d78ba7aea34a5eb377563f53e826c4ad65683 [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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
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"
71#include "usctest.h"
72
73int cflag; /* flag to indicate child process status */
74pid_t cpid; /* child process id */
75
subrata_modak56207ce2009-03-23 13:35:39 +000076char *TCID = "pause03"; /* Test program identifier. */
77int TST_TOTAL = 1; /* Total number of test cases. */
plars865695b2001-08-27 22:15:12 +000078extern int Tst_count; /* Test Case counter for tst_* routines */
79
robbiewd34d5812005-07-11 22:28:09 +000080void do_child(); /* Function to run in child process */
plars865695b2001-08-27 22:15:12 +000081void setup(); /* Main setup function of test */
82void cleanup(); /* cleanup function for the test */
83void sig_handle(int sig); /* signal handler for SIGCLD */
84
subrata_modak56207ce2009-03-23 13:35:39 +000085int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000086{
87 int lc; /* loop counter */
88 char *msg; /* message returned from parse_opts */
89 int status; /* child process exit status */
90 int ret_val; /* return value for wait() */
subrata_modak56207ce2009-03-23 13:35:39 +000091
plars865695b2001-08-27 22:15:12 +000092 /* Parse standard options given to run the test. */
Garrett Cooper45e285d2010-11-22 12:19:25 -080093 msg = parse_opts(ac, av, NULL, NULL);
94 if (msg != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -080095 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +000096 }
robbiewd34d5812005-07-11 22:28:09 +000097#ifdef UCLINUX
98 maybe_run_child(&do_child, "");
99#endif
100
plars865695b2001-08-27 22:15:12 +0000101 /* Perform global setup for test */
102 setup();
103
104 /* Check looping state if -i option given */
105 for (lc = 0; TEST_LOOPING(lc); lc++) {
106
107 /* Reset Tst_count in case we are looping. */
subrata_modak56207ce2009-03-23 13:35:39 +0000108 Tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000109
110 /* Creat a new process using fork() */
vapierfed9da32006-02-19 09:25:08 +0000111 if ((cpid = FORK_OR_VFORK()) == -1) {
plars865695b2001-08-27 22:15:12 +0000112 tst_brkm(TBROK, cleanup, "fork() failed");
113 }
114
subrata_modak56207ce2009-03-23 13:35:39 +0000115 if (cpid == 0) { /* Child process */
robbiewd34d5812005-07-11 22:28:09 +0000116#ifdef UCLINUX
117 if (self_exec(av[0], "") < 0) {
118 tst_brkm(TBROK, cleanup, "self_exec failed");
119 }
120#else
121 do_child();
122#endif
plars865695b2001-08-27 22:15:12 +0000123 }
124
125 /* Parent process */
126 /* sleep to ensure the child executes */
127 sleep(1);
128
129 /* Check for the value of cflag */
130 if (cflag == 1) {
131 /*
132 * Indicates that child terminated
133 * before receipt of SIGKILL signal.
134 */
135 tst_brkm(TFAIL, cleanup,
136 "Child exited before SIGKILL signal");
137 }
138
139 /* Send the SIGKILL signal now */
140 kill(cpid, SIGKILL);
141
142 /* sleep to ensure the signal sent is effected */
143 sleep(1);
144
145 /* Verify again the value of cflag */
146 if (cflag == 0) {
147 /* Child still exists */
148 tst_resm(TFAIL, "Child still exists, "
149 "pause() still active");
150 cleanup();
151 }
152
153 ret_val = wait(&status);
154
155 /*
156 * Verify that wait returned after child process termination
157 * due to receipt of SIGKILL signal.
158 */
subrata_modak56207ce2009-03-23 13:35:39 +0000159 if (WTERMSIG(status) == SIGKILL) {
plars865695b2001-08-27 22:15:12 +0000160 ret_val = wait(&status);
161 if ((ret_val == -1) && (errno == ECHILD)) {
162 /*
163 * Child is no longer accessible and pause()
164 * functionality is successful.
165 */
166 tst_resm(TPASS, "Functionality of "
167 "pause() is correct");
168 } else {
169 tst_resm(TFAIL, "wait() failed due to "
vapier356d38a2009-08-28 13:36:21 +0000170 "unkown reason, ret_val=%d, "
plars865695b2001-08-27 22:15:12 +0000171 "errno=%d", ret_val, errno);
172 }
173 } else {
174 tst_resm(TFAIL, "Child terminated not due to "
175 "SIGKILL, errno = %d", errno);
176 }
177
178 /* reset cflag in case we are looping */
179 cflag = 0;
180
subrata_modak56207ce2009-03-23 13:35:39 +0000181 } /* End for TEST_LOOPING */
plars865695b2001-08-27 22:15:12 +0000182
183 /* Call cleanup() to undo setup done for the test. */
184 cleanup();
185
subrata_modak43337a32009-02-26 11:43:51 +0000186 return 0;
subrata_modak56207ce2009-03-23 13:35:39 +0000187} /* End main */
plars865695b2001-08-27 22:15:12 +0000188
189/*
robbiewd34d5812005-07-11 22:28:09 +0000190 * do_child()
191 */
subrata_modak56207ce2009-03-23 13:35:39 +0000192void do_child()
robbiewd34d5812005-07-11 22:28:09 +0000193{
194 /* Suspend the child using pause() */
195 TEST(pause());
subrata_modakbdbaec52009-02-26 12:14:51 +0000196
robbiewd34d5812005-07-11 22:28:09 +0000197 /* print the message if pause() returned */
198 tst_resm(TFAIL, "Unexpected return from pause()");
199 /* Loop infinitely */
subrata_modak56207ce2009-03-23 13:35:39 +0000200 while (1) ;
robbiewd34d5812005-07-11 22:28:09 +0000201}
202
203/*
plars865695b2001-08-27 22:15:12 +0000204 * setup() - performs all ONE TIME setup for this test.
subrata_modak56207ce2009-03-23 13:35:39 +0000205 * Setup signal handler to catch SIGCLD signal.
plars865695b2001-08-27 22:15:12 +0000206 */
subrata_modak56207ce2009-03-23 13:35:39 +0000207void setup()
plars865695b2001-08-27 22:15:12 +0000208{
209 /* capture signals */
210 tst_sig(FORK, DEF_HANDLER, cleanup);
211
212 /* Pause if that option was specified */
213 TEST_PAUSE;
214
215 /* Initialise cflag */
216 cflag = 0;
217
218 /* Catch SIGCLD */
219 signal(SIGCLD, sig_handle);
220}
221
222/*
223 * sig_handle(int sig)
224 * This is the signal handler to handle the SIGCLD signal.
225 * When the child terminates and the parent gets the SIGCLD signal
subrata_modak4bb656a2009-02-26 12:02:09 +0000226 * the handler gets executed and then the cflag variable is set to
plars865695b2001-08-27 22:15:12 +0000227 * indicate the child has terminated.
228 */
subrata_modak56207ce2009-03-23 13:35:39 +0000229void sig_handle(int sig)
plars865695b2001-08-27 22:15:12 +0000230{
231 /* Set the cflag variable */
232 cflag = 1;
233}
234
235/*
236 * cleanup() - performs all ONE TIME cleanup for this test at
237 * completion or premature exit.
238 */
subrata_modak56207ce2009-03-23 13:35:39 +0000239void cleanup()
plars865695b2001-08-27 22:15:12 +0000240{
241 /*
242 * print timing stats if that option was specified.
243 * print errno log if that option was specified.
244 */
245 TEST_CLEANUP;
246
247 /* Cleanup the child if still active */
248 kill(cpid, SIGKILL);
249
250 /* exit with return code appropriate for results */
251 tst_exit();
252}