blob: c4df76df73e8e898c9733bc44ec3e33e686fa4ed [file] [log] [blame]
robbiewc72e43f2003-08-01 15:46:23 +00001/*
2 * Copyright (c) International Business Machines Corp., 2003.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080013 * with this program; if not, write the Free Software Foundation, Inc.,
14 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
robbiewc72e43f2003-08-01 15:46:23 +000015 *
16 */
17/**********************************************************
subrata_modak4bb656a2009-02-26 12:02:09 +000018 *
19 * TEST IDENTIFIER : clone07
20 *
robbiewc72e43f2003-08-01 15:46:23 +000021 * EXECUTED BY : anyone
subrata_modak4bb656a2009-02-26 12:02:09 +000022 *
robbiewc72e43f2003-08-01 15:46:23 +000023 * TEST TITLE : glibc bug test for clone(2)
subrata_modak4bb656a2009-02-26 12:02:09 +000024 *
robbiewc72e43f2003-08-01 15:46:23 +000025 * TEST CASE TOTAL : 1
subrata_modak4bb656a2009-02-26 12:02:09 +000026 *
robbiewc72e43f2003-08-01 15:46:23 +000027 * AUTHOR : Robbie Williamson <robbiew@us.ibm.com>
subrata_modak4bb656a2009-02-26 12:02:09 +000028 *
robbiewc72e43f2003-08-01 15:46:23 +000029 * SIGNALS
subrata_modak56207ce2009-03-23 13:35:39 +000030 * Uses SIGUSR1 to pause before test if option set.
31 * (See the parse_opts(3) man page).
robbiewc72e43f2003-08-01 15:46:23 +000032 *
33 * DESCRIPTION
34 * This is a test for a glibc bug for the clone(2) system call.
subrata_modak4bb656a2009-02-26 12:02:09 +000035 *
subrata_modak56207ce2009-03-23 13:35:39 +000036 * Setup:
37 * Setup signal handling.
robbiewc72e43f2003-08-01 15:46:23 +000038 * Pause for SIGUSR1 if option specified.
subrata_modak4bb656a2009-02-26 12:02:09 +000039 *
subrata_modak56207ce2009-03-23 13:35:39 +000040 * Test:
robbiewc72e43f2003-08-01 15:46:23 +000041 * Loop if the proper options are given.
subrata_modak56207ce2009-03-23 13:35:39 +000042 * Call clone() with only SIGCHLD flag
robbiewc72e43f2003-08-01 15:46:23 +000043 *
44 * CHILD:
45 * return 0;
46 *
47 * PARENT:
48 * wait for child to finish
subrata_modak4bb656a2009-02-26 12:02:09 +000049 * If a SIGSEGV is not received by the child for using return()
robbiewc72e43f2003-08-01 15:46:23 +000050 * test passed
51 * else
52 * test failed
subrata_modak4bb656a2009-02-26 12:02:09 +000053 *
subrata_modak56207ce2009-03-23 13:35:39 +000054 * Cleanup:
55 * Print errno log and/or timing stats if options given
subrata_modak4bb656a2009-02-26 12:02:09 +000056 *
robbiewc72e43f2003-08-01 15:46:23 +000057 * USAGE: <for command-line>
58 * clone01 [-c n] [-e] [-i n] [-I x] [-P x] [-t] [-h] [-f] [-p]
59 * where, -c n : Run n copies concurrently.
60 * -e : Turn on errno logging.
61 * -h : Show help screen
62 * -f : Turn off functional testing
63 * -i n : Execute test n times.
64 * -I x : Execute test for x seconds.
65 * -p : Pause for SIGUSR1 before starting
66 * -P x : Pause for x seconds between iterations.
67 * -t : Turn on syscall timing.
68 *
69 ****************************************************************/
70
robbiewd34d5812005-07-11 22:28:09 +000071#if defined UCLINUX && !__THROW
72/* workaround for libc bug */
73#define __THROW
74#endif
75
robbiewc72e43f2003-08-01 15:46:23 +000076#include <errno.h>
77#include <sched.h>
78#include <sys/wait.h>
79#include "test.h"
80#include "usctest.h"
robbiewf41288e2003-10-10 15:32:03 +000081#include "clone_platform.h"
robbiewc72e43f2003-08-01 15:46:23 +000082
robbiewc72e43f2003-08-01 15:46:23 +000083#define TRUE 1
84#define FALSE 0
85
robbiewc72e43f2003-08-01 15:46:23 +000086static void setup();
87static void cleanup();
88static int do_child();
89
subrata_modak56207ce2009-03-23 13:35:39 +000090char *TCID = "clone07"; /* Test program identifier. */
91int TST_TOTAL = 1; /* Total number of test cases. */
robbiewc72e43f2003-08-01 15:46:23 +000092
93void sigsegv_handler(int);
94void sigusr2_handler(int);
95static int child_pid;
96static int fail = FALSE;
97
subrata_modak56207ce2009-03-23 13:35:39 +000098int main(int ac, char **av)
robbiewc72e43f2003-08-01 15:46:23 +000099{
100
Jan Stancek443d16e2012-12-03 13:19:57 +0100101 int lc, status;
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200102 char *msg;
robbiewc72e43f2003-08-01 15:46:23 +0000103 void *child_stack; /* stack for child */
subrata_modak56207ce2009-03-23 13:35:39 +0000104
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800105 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800106 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
robbiewc72e43f2003-08-01 15:46:23 +0000107
robbiewc72e43f2003-08-01 15:46:23 +0000108 setup();
109
subrata_modak56207ce2009-03-23 13:35:39 +0000110 for (lc = 0; TEST_LOOPING(lc); lc++) {
robbiewc72e43f2003-08-01 15:46:23 +0000111
subrata_modak56207ce2009-03-23 13:35:39 +0000112 Tst_count = 0;
subrata_modak9d718392009-04-13 14:35:12 +0000113 /* Allocate stack for child */
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800114 if ((child_stack = (void *) malloc(CHILD_STACK_SIZE)) == NULL) {
subrata_modak9d718392009-04-13 14:35:12 +0000115 tst_brkm(TBROK, cleanup, "Cannot allocate stack for child");
116 }
117
subrata_modak4bb656a2009-02-26 12:02:09 +0000118 /*
robbiewc72e43f2003-08-01 15:46:23 +0000119 * Call clone(2)
120 */
vapierf6d7f092009-11-03 20:07:35 +0000121 child_pid = ltp_clone(SIGCHLD, do_child, NULL,
122 CHILD_STACK_SIZE, child_stack);
Jan Stancek443d16e2012-12-03 13:19:57 +0100123 if ((wait(&status)) == -1)
124 tst_brkm(TBROK|TERRNO, cleanup,
125 "wait failed, status: %d", status);
robbiewc72e43f2003-08-01 15:46:23 +0000126 free(child_stack);
Garrett Cooper2c282152010-12-16 00:55:50 -0800127 }
robbiewc72e43f2003-08-01 15:46:23 +0000128
subrata_modak56207ce2009-03-23 13:35:39 +0000129 if (fail == FALSE)
130 tst_resm(TPASS,
131 "Use of return() in child did not cause SIGSEGV");
132 else {
133 tst_resm(TFAIL, "Use of return() in child caused SIGSEGV");
134 }
135
robbiewc72e43f2003-08-01 15:46:23 +0000136 cleanup();
subrata_modakbdbaec52009-02-26 12:14:51 +0000137
Garrett Cooperfbb20142010-12-17 01:57:48 -0800138 tst_exit();
139
Garrett Cooper2c282152010-12-16 00:55:50 -0800140}
robbiewc72e43f2003-08-01 15:46:23 +0000141
142/* setup() - performs all ONE TIME setup for this test */
subrata_modak56207ce2009-03-23 13:35:39 +0000143void setup()
robbiewc72e43f2003-08-01 15:46:23 +0000144{
145 struct sigaction def_act;
146 struct sigaction act;
147
robbiewc72e43f2003-08-01 15:46:23 +0000148 TEST_PAUSE;
149
subrata_modakbdbaec52009-02-26 12:14:51 +0000150 act.sa_handler = sigsegv_handler;
robbiewc72e43f2003-08-01 15:46:23 +0000151 act.sa_flags = SA_RESTART;
subrata_modak56207ce2009-03-23 13:35:39 +0000152 if ((sigaction(SIGSEGV, &act, NULL)) == -1) {
vapier0874e6f2009-08-28 12:07:53 +0000153 tst_resm(TWARN|TERRNO,
subrata_modak56207ce2009-03-23 13:35:39 +0000154 "sigaction() for SIGSEGV failed in test_setup()");
155 }
robbiewc72e43f2003-08-01 15:46:23 +0000156
subrata_modak56207ce2009-03-23 13:35:39 +0000157 /* Setup signal handler for SIGUSR2 */
158 def_act.sa_handler = sigusr2_handler;
159 def_act.sa_flags = SA_RESTART | SA_RESETHAND;
robbiewc72e43f2003-08-01 15:46:23 +0000160
subrata_modak56207ce2009-03-23 13:35:39 +0000161 if ((sigaction(SIGUSR2, &def_act, NULL)) == -1) {
vapier0874e6f2009-08-28 12:07:53 +0000162 tst_resm(TWARN|TERRNO,
subrata_modak56207ce2009-03-23 13:35:39 +0000163 "sigaction() for SIGUSR2 failed in test_setup()");
164 }
robbiewc72e43f2003-08-01 15:46:23 +0000165
Garrett Cooper2c282152010-12-16 00:55:50 -0800166}
robbiewc72e43f2003-08-01 15:46:23 +0000167
subrata_modak4bb656a2009-02-26 12:02:09 +0000168/*
robbiewc72e43f2003-08-01 15:46:23 +0000169 *cleanup() - performs all ONE TIME cleanup for this test at
170 * completion or premature exit.
171 */
subrata_modak56207ce2009-03-23 13:35:39 +0000172void cleanup()
robbiewc72e43f2003-08-01 15:46:23 +0000173{
174
175 /*
176 * print timing stats if that option was specified.
177 * print errno log if that option was specified.
178 */
179 TEST_CLEANUP;
180
subrata_modak56207ce2009-03-23 13:35:39 +0000181 kill(child_pid, SIGKILL);
Garrett Cooper2c282152010-12-16 00:55:50 -0800182
183}
robbiewc72e43f2003-08-01 15:46:23 +0000184
185/*
186 * do_child() - function executed by child
187 */
subrata_modak56207ce2009-03-23 13:35:39 +0000188int do_child(void)
robbiewc72e43f2003-08-01 15:46:23 +0000189{
190 return 0;
191}
192
subrata_modak56207ce2009-03-23 13:35:39 +0000193void sigsegv_handler(int sig)
robbiewc72e43f2003-08-01 15:46:23 +0000194{
subrata_modak56207ce2009-03-23 13:35:39 +0000195 if (child_pid == 0) {
196 kill(getppid(), SIGUSR2);
197 _exit(42);
198 }
robbiewc72e43f2003-08-01 15:46:23 +0000199}
200
201/* sig_default_handler() - Default handler for parent */
subrata_modak56207ce2009-03-23 13:35:39 +0000202void sigusr2_handler(int sig)
robbiewc72e43f2003-08-01 15:46:23 +0000203{
subrata_modak56207ce2009-03-23 13:35:39 +0000204 if (child_pid != 0) {
205 fail = TRUE;
206 }
Chris Dearmanec6edca2012-10-17 19:54:01 -0700207}