blob: 80cf7e5b369ea730bce651e6d92d925c1adf34ee [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 * Test Name: sigalstack01
22 *
23 * Test Description:
24 * Send a signal using the main stack. While executing the signal handler
25 * compare a variable's address lying on the main stack with the stack
26 * boundaries returned by sigaltstack().
27 *
28 * Expected Result:
29 * sigaltstack() should succeed to get/set signal alternate stack context.
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>
51 * sigaltstack01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
52 * where, -c n : Run n copies concurrently.
53 * -e : Turn on errno logging.
54 * -f : Turn off functionality Testing.
55 * -i n : Execute test n times.
56 * -I x : Execute test for x seconds.
57 * -P x : Pause for x seconds between iterations.
58 * -t : Turn on syscall timing.
59 *
60 * History
61 * 07/2001 John George
62 * -Ported
63 *
64 * Restrictions:
65 * This test should be run by 'super-user' (root) only and must run from
66 * shell which sets up for test.
67 *
68 */
69
70#include <stdio.h>
71#include <sys/types.h>
72#include <unistd.h>
73#include <signal.h>
74#include <string.h>
75#include <ucontext.h>
76#include <errno.h>
77
78#include "test.h"
plars865695b2001-08-27 22:15:12 +000079
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020080char *TCID = "sigaltstack01";
81int TST_TOTAL = 1;
Wanlong Gao354ebb42012-12-07 10:10:04 +080082
subrata_modak56207ce2009-03-23 13:35:39 +000083void *addr, *main_stk; /* address of main stack for signal */
plars865695b2001-08-27 22:15:12 +000084int got_signal = 0;
85pid_t my_pid; /* test process id */
86
87stack_t sigstk, osigstk; /* signal stack storing struct. */
88struct sigaction act, oact; /* sigaction() struct. */
89
Jan Stancekeb3aa4e2014-02-25 14:42:58 +010090void setup(void); /* Main setup function of test */
91void cleanup(void); /* cleanup function for the test */
92void sig_handler(int); /* signal catching function */
plars865695b2001-08-27 22:15:12 +000093
plars74948ad2002-11-14 16:16:14 +000094int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000095{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020096 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020097 const char *msg;
plars74948ad2002-11-14 16:16:14 +000098 void *alt_stk; /* address of alternate stack for signal */
plars865695b2001-08-27 22:15:12 +000099
Garrett Cooper45e285d2010-11-22 12:19:25 -0800100 msg = parse_opts(ac, av, NULL, NULL);
101 if (msg != NULL) {
plars865695b2001-08-27 22:15:12 +0000102 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -0800103
Wanlong Gao354ebb42012-12-07 10:10:04 +0800104 }
plars865695b2001-08-27 22:15:12 +0000105
plars865695b2001-08-27 22:15:12 +0000106 setup();
107
plars865695b2001-08-27 22:15:12 +0000108 for (lc = 0; TEST_LOOPING(lc); lc++) {
Garrett Cooper2c282152010-12-16 00:55:50 -0800109
Caspar Zhangd59a6592013-03-07 14:59:12 +0800110 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000111
112 /* Call sigaltstack() to set up an alternate stack */
113 sigstk.ss_size = SIGSTKSZ;
114 sigstk.ss_flags = 0;
115 TEST(sigaltstack(&sigstk, &osigstk));
116
plars865695b2001-08-27 22:15:12 +0000117 if (TEST_RETURN == -1) {
subrata_modak56207ce2009-03-23 13:35:39 +0000118 tst_resm(TFAIL,
plars865695b2001-08-27 22:15:12 +0000119 "sigaltstack() Failed, errno=%d : %s",
120 TEST_ERRNO, strerror(TEST_ERRNO));
121 } else {
Cyril Hrubise38b9612014-06-02 17:20:57 +0200122 /* Set up the signal handler for 'SIGUSR1' */
123 act.sa_flags = SA_ONSTACK;
124 act.sa_handler = (void (*)())sig_handler;
125 if ((sigaction(SIGUSR1, &act, &oact)) == -1) {
126 tst_brkm(TFAIL, cleanup, "sigaction() "
127 "fails to trap signal "
128 "delivered on alt. stack, "
129 "error=%d", errno);
130 }
131
132 /* Deliver signal onto the alternate stack */
133 kill(my_pid, SIGUSR1);
134
135 /* wait till the signal arrives */
136 while (!got_signal) ;
137
138 got_signal = 0;
139 alt_stk = addr;
140
plars865695b2001-08-27 22:15:12 +0000141 /*
Cyril Hrubise38b9612014-06-02 17:20:57 +0200142 * First,
143 * Check that alt_stk is within the
144 * alternate stk boundaries
145 *
146 * Second,
147 * Check that main_stk is outside the
148 * alternate stk boundaries.
plars865695b2001-08-27 22:15:12 +0000149 */
Cyril Hrubise38b9612014-06-02 17:20:57 +0200150 if ((alt_stk < sigstk.ss_sp) &&
151 (alt_stk > (sigstk.ss_sp + SIGSTKSZ))) {
152 tst_resm(TFAIL,
153 "alt. stack is not within the "
154 "alternate stk boundaries");
155 } else if ((main_stk >= sigstk.ss_sp) &&
156 (main_stk <=
157 (sigstk.ss_sp + SIGSTKSZ))) {
158 tst_resm(TFAIL,
159 "main stk. not outside the "
160 "alt. stack boundaries");
plars865695b2001-08-27 22:15:12 +0000161 } else {
Cyril Hrubise38b9612014-06-02 17:20:57 +0200162 tst_resm(TPASS,
163 "Functionality of "
164 "sigaltstack() successful");
plars865695b2001-08-27 22:15:12 +0000165 }
166 }
Caspar Zhangd59a6592013-03-07 14:59:12 +0800167 tst_count++; /* incr. TEST_LOOP counter */
Garrett Cooper2c282152010-12-16 00:55:50 -0800168 }
plars865695b2001-08-27 22:15:12 +0000169
plars865695b2001-08-27 22:15:12 +0000170 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800171 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800172}
plars865695b2001-08-27 22:15:12 +0000173
174/*
175 * void
176 * setup() - performs all ONE TIME setup for this test.
177 * Capture SIGUSR1 on the main stack.
178 * send the signal 'SIGUSER1' to the process.
179 * wait till the signal arrives.
180 * Allocate memory for the alternative stack.
181 */
Jan Stancekeb3aa4e2014-02-25 14:42:58 +0100182void setup(void)
plars865695b2001-08-27 22:15:12 +0000183{
Garrett Cooper2c282152010-12-16 00:55:50 -0800184
plars865695b2001-08-27 22:15:12 +0000185 tst_sig(FORK, DEF_HANDLER, cleanup);
186
plars865695b2001-08-27 22:15:12 +0000187 TEST_PAUSE;
188
189 /* Get the process id of test process */
190 my_pid = getpid();
191
192 /* Capture SIGUSR1 on the main stack */
Jan Stancekeb3aa4e2014-02-25 14:42:58 +0100193 act.sa_handler = (void (*)(int))sig_handler;
plars865695b2001-08-27 22:15:12 +0000194 if ((sigaction(SIGUSR1, &act, &oact)) == -1) {
195 tst_brkm(TFAIL, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000196 "sigaction() fails in setup, errno=%d", errno);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800197 }
plars865695b2001-08-27 22:15:12 +0000198
199 /* Send the signal to the test process */
200 kill(my_pid, SIGUSR1);
201
202 /* Wait till the signal arrives */
subrata_modak56207ce2009-03-23 13:35:39 +0000203 while (!got_signal) ;
plars865695b2001-08-27 22:15:12 +0000204
205 got_signal = 0;
206 main_stk = addr;
207
208 /* Allocate memory for the alternate stack */
Cyril Hrubisd218f342014-09-23 13:14:56 +0200209 if ((sigstk.ss_sp = malloc(SIGSTKSZ)) == NULL) {
plars865695b2001-08-27 22:15:12 +0000210 tst_brkm(TFAIL, cleanup,
211 "could not allocate memory for the alternate stack");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800212 }
plars865695b2001-08-27 22:15:12 +0000213}
214
215/*
216 * void
217 * sig_handler() - signal catching function.
218 * This functions is called when the signal 'SIGUSR1' is delivered to
219 * the test process and trapped by sigaction().
220 *
221 * This function updates 'addr' variable and sets got_signal value.
222 */
Jan Stancekeb3aa4e2014-02-25 14:42:58 +0100223void sig_handler(int n)
subrata_modak56207ce2009-03-23 13:35:39 +0000224{
plars865695b2001-08-27 22:15:12 +0000225 int i;
226
Jan Stancekeb3aa4e2014-02-25 14:42:58 +0100227 (void) n;
plars74948ad2002-11-14 16:16:14 +0000228 addr = &i;
plars865695b2001-08-27 22:15:12 +0000229 got_signal = 1;
230}
231
232/*
233 * void
234 * cleanup() - performs all ONE TIME cleanup for this test at
235 * completion or premature exit.
236 * Free the memory allocated for alternate stack.
237 */
Jan Stancekeb3aa4e2014-02-25 14:42:58 +0100238void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000239{
plars865695b2001-08-27 22:15:12 +0000240
241 free(sigstk.ss_sp);
242
Chris Dearmanec6edca2012-10-17 19:54:01 -0700243}