1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker *
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) International Business Machines Corp., 2001
4*49cdfc7eSAndroid Build Coastguard Worker *
5*49cdfc7eSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
6*49cdfc7eSAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
7*49cdfc7eSAndroid Build Coastguard Worker * the Free Software Foundation; either version 2 of the License, or
8*49cdfc7eSAndroid Build Coastguard Worker * (at your option) any later version.
9*49cdfc7eSAndroid Build Coastguard Worker *
10*49cdfc7eSAndroid Build Coastguard Worker * This program is distributed in the hope that it will be useful,
11*49cdfc7eSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*49cdfc7eSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13*49cdfc7eSAndroid Build Coastguard Worker * the GNU General Public License for more details.
14*49cdfc7eSAndroid Build Coastguard Worker *
15*49cdfc7eSAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License
16*49cdfc7eSAndroid Build Coastguard Worker * along with this program; if not, write to the Free Software
17*49cdfc7eSAndroid Build Coastguard Worker * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*49cdfc7eSAndroid Build Coastguard Worker */
19*49cdfc7eSAndroid Build Coastguard Worker
20*49cdfc7eSAndroid Build Coastguard Worker /*
21*49cdfc7eSAndroid Build Coastguard Worker * Test Name: sigalstack01
22*49cdfc7eSAndroid Build Coastguard Worker *
23*49cdfc7eSAndroid Build Coastguard Worker * Test Description:
24*49cdfc7eSAndroid Build Coastguard Worker * Send a signal using the main stack. While executing the signal handler
25*49cdfc7eSAndroid Build Coastguard Worker * compare a variable's address lying on the main stack with the stack
26*49cdfc7eSAndroid Build Coastguard Worker * boundaries returned by sigaltstack().
27*49cdfc7eSAndroid Build Coastguard Worker *
28*49cdfc7eSAndroid Build Coastguard Worker * Expected Result:
29*49cdfc7eSAndroid Build Coastguard Worker * sigaltstack() should succeed to get/set signal alternate stack context.
30*49cdfc7eSAndroid Build Coastguard Worker *
31*49cdfc7eSAndroid Build Coastguard Worker * Algorithm:
32*49cdfc7eSAndroid Build Coastguard Worker * Setup:
33*49cdfc7eSAndroid Build Coastguard Worker * Setup signal handling.
34*49cdfc7eSAndroid Build Coastguard Worker * Pause for SIGUSR1 if option specified.
35*49cdfc7eSAndroid Build Coastguard Worker *
36*49cdfc7eSAndroid Build Coastguard Worker * Test:
37*49cdfc7eSAndroid Build Coastguard Worker * Loop if the proper options are given.
38*49cdfc7eSAndroid Build Coastguard Worker * Execute system call
39*49cdfc7eSAndroid Build Coastguard Worker * Check return code, if system call failed (return=-1)
40*49cdfc7eSAndroid Build Coastguard Worker * Log the errno and Issue a FAIL message.
41*49cdfc7eSAndroid Build Coastguard Worker * Otherwise,
42*49cdfc7eSAndroid Build Coastguard Worker * Verify the Functionality of system call
43*49cdfc7eSAndroid Build Coastguard Worker * if successful,
44*49cdfc7eSAndroid Build Coastguard Worker * Issue Functionality-Pass message.
45*49cdfc7eSAndroid Build Coastguard Worker * Otherwise,
46*49cdfc7eSAndroid Build Coastguard Worker * Issue Functionality-Fail message.
47*49cdfc7eSAndroid Build Coastguard Worker * Cleanup:
48*49cdfc7eSAndroid Build Coastguard Worker * Print errno log and/or timing stats if options given
49*49cdfc7eSAndroid Build Coastguard Worker *
50*49cdfc7eSAndroid Build Coastguard Worker * Usage: <for command-line>
51*49cdfc7eSAndroid Build Coastguard Worker * sigaltstack01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
52*49cdfc7eSAndroid Build Coastguard Worker * where, -c n : Run n copies concurrently.
53*49cdfc7eSAndroid Build Coastguard Worker * -e : Turn on errno logging.
54*49cdfc7eSAndroid Build Coastguard Worker * -f : Turn off functionality Testing.
55*49cdfc7eSAndroid Build Coastguard Worker * -i n : Execute test n times.
56*49cdfc7eSAndroid Build Coastguard Worker * -I x : Execute test for x seconds.
57*49cdfc7eSAndroid Build Coastguard Worker * -P x : Pause for x seconds between iterations.
58*49cdfc7eSAndroid Build Coastguard Worker * -t : Turn on syscall timing.
59*49cdfc7eSAndroid Build Coastguard Worker *
60*49cdfc7eSAndroid Build Coastguard Worker * History
61*49cdfc7eSAndroid Build Coastguard Worker * 07/2001 John George
62*49cdfc7eSAndroid Build Coastguard Worker * -Ported
63*49cdfc7eSAndroid Build Coastguard Worker *
64*49cdfc7eSAndroid Build Coastguard Worker * Restrictions:
65*49cdfc7eSAndroid Build Coastguard Worker * This test should be run by 'super-user' (root) only and must run from
66*49cdfc7eSAndroid Build Coastguard Worker * shell which sets up for test.
67*49cdfc7eSAndroid Build Coastguard Worker *
68*49cdfc7eSAndroid Build Coastguard Worker */
69*49cdfc7eSAndroid Build Coastguard Worker
70*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
71*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
72*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
73*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
74*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
75*49cdfc7eSAndroid Build Coastguard Worker #include <ucontext.h>
76*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
77*49cdfc7eSAndroid Build Coastguard Worker
78*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
79*49cdfc7eSAndroid Build Coastguard Worker
80*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "sigaltstack01";
81*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 1;
82*49cdfc7eSAndroid Build Coastguard Worker
83*49cdfc7eSAndroid Build Coastguard Worker void *addr, *main_stk; /* address of main stack for signal */
84*49cdfc7eSAndroid Build Coastguard Worker int got_signal = 0;
85*49cdfc7eSAndroid Build Coastguard Worker pid_t my_pid; /* test process id */
86*49cdfc7eSAndroid Build Coastguard Worker
87*49cdfc7eSAndroid Build Coastguard Worker stack_t sigstk, osigstk; /* signal stack storing struct. */
88*49cdfc7eSAndroid Build Coastguard Worker struct sigaction act, oact; /* sigaction() struct. */
89*49cdfc7eSAndroid Build Coastguard Worker
90*49cdfc7eSAndroid Build Coastguard Worker void setup(void); /* Main setup function of test */
91*49cdfc7eSAndroid Build Coastguard Worker void cleanup(void); /* cleanup function for the test */
92*49cdfc7eSAndroid Build Coastguard Worker void sig_handler(int); /* signal catching function */
93*49cdfc7eSAndroid Build Coastguard Worker
main(int ac,char ** av)94*49cdfc7eSAndroid Build Coastguard Worker int main(int ac, char **av)
95*49cdfc7eSAndroid Build Coastguard Worker {
96*49cdfc7eSAndroid Build Coastguard Worker int lc;
97*49cdfc7eSAndroid Build Coastguard Worker void *alt_stk; /* address of alternate stack for signal */
98*49cdfc7eSAndroid Build Coastguard Worker
99*49cdfc7eSAndroid Build Coastguard Worker tst_parse_opts(ac, av, NULL, NULL);
100*49cdfc7eSAndroid Build Coastguard Worker
101*49cdfc7eSAndroid Build Coastguard Worker setup();
102*49cdfc7eSAndroid Build Coastguard Worker
103*49cdfc7eSAndroid Build Coastguard Worker for (lc = 0; TEST_LOOPING(lc); lc++) {
104*49cdfc7eSAndroid Build Coastguard Worker
105*49cdfc7eSAndroid Build Coastguard Worker tst_count = 0;
106*49cdfc7eSAndroid Build Coastguard Worker
107*49cdfc7eSAndroid Build Coastguard Worker /* Call sigaltstack() to set up an alternate stack */
108*49cdfc7eSAndroid Build Coastguard Worker sigstk.ss_size = SIGSTKSZ;
109*49cdfc7eSAndroid Build Coastguard Worker sigstk.ss_flags = 0;
110*49cdfc7eSAndroid Build Coastguard Worker TEST(sigaltstack(&sigstk, &osigstk));
111*49cdfc7eSAndroid Build Coastguard Worker
112*49cdfc7eSAndroid Build Coastguard Worker if (TEST_RETURN == -1) {
113*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TFAIL,
114*49cdfc7eSAndroid Build Coastguard Worker "sigaltstack() Failed, errno=%d : %s",
115*49cdfc7eSAndroid Build Coastguard Worker TEST_ERRNO, strerror(TEST_ERRNO));
116*49cdfc7eSAndroid Build Coastguard Worker } else {
117*49cdfc7eSAndroid Build Coastguard Worker /* Set up the signal handler for 'SIGUSR1' */
118*49cdfc7eSAndroid Build Coastguard Worker act.sa_flags = SA_ONSTACK;
119*49cdfc7eSAndroid Build Coastguard Worker act.sa_handler = (void (*)())sig_handler;
120*49cdfc7eSAndroid Build Coastguard Worker if ((sigaction(SIGUSR1, &act, &oact)) == -1) {
121*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TFAIL, cleanup, "sigaction() "
122*49cdfc7eSAndroid Build Coastguard Worker "fails to trap signal "
123*49cdfc7eSAndroid Build Coastguard Worker "delivered on alt. stack, "
124*49cdfc7eSAndroid Build Coastguard Worker "error=%d", errno);
125*49cdfc7eSAndroid Build Coastguard Worker }
126*49cdfc7eSAndroid Build Coastguard Worker
127*49cdfc7eSAndroid Build Coastguard Worker /* Deliver signal onto the alternate stack */
128*49cdfc7eSAndroid Build Coastguard Worker kill(my_pid, SIGUSR1);
129*49cdfc7eSAndroid Build Coastguard Worker
130*49cdfc7eSAndroid Build Coastguard Worker /* wait till the signal arrives */
131*49cdfc7eSAndroid Build Coastguard Worker while (!got_signal) ;
132*49cdfc7eSAndroid Build Coastguard Worker
133*49cdfc7eSAndroid Build Coastguard Worker got_signal = 0;
134*49cdfc7eSAndroid Build Coastguard Worker alt_stk = addr;
135*49cdfc7eSAndroid Build Coastguard Worker
136*49cdfc7eSAndroid Build Coastguard Worker /*
137*49cdfc7eSAndroid Build Coastguard Worker * First,
138*49cdfc7eSAndroid Build Coastguard Worker * Check that alt_stk is within the
139*49cdfc7eSAndroid Build Coastguard Worker * alternate stk boundaries
140*49cdfc7eSAndroid Build Coastguard Worker *
141*49cdfc7eSAndroid Build Coastguard Worker * Second,
142*49cdfc7eSAndroid Build Coastguard Worker * Check that main_stk is outside the
143*49cdfc7eSAndroid Build Coastguard Worker * alternate stk boundaries.
144*49cdfc7eSAndroid Build Coastguard Worker */
145*49cdfc7eSAndroid Build Coastguard Worker if ((alt_stk < sigstk.ss_sp) &&
146*49cdfc7eSAndroid Build Coastguard Worker (alt_stk > (sigstk.ss_sp + SIGSTKSZ))) {
147*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TFAIL,
148*49cdfc7eSAndroid Build Coastguard Worker "alt. stack is not within the "
149*49cdfc7eSAndroid Build Coastguard Worker "alternate stk boundaries");
150*49cdfc7eSAndroid Build Coastguard Worker } else if ((main_stk >= sigstk.ss_sp) &&
151*49cdfc7eSAndroid Build Coastguard Worker (main_stk <=
152*49cdfc7eSAndroid Build Coastguard Worker (sigstk.ss_sp + SIGSTKSZ))) {
153*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TFAIL,
154*49cdfc7eSAndroid Build Coastguard Worker "main stk. not outside the "
155*49cdfc7eSAndroid Build Coastguard Worker "alt. stack boundaries");
156*49cdfc7eSAndroid Build Coastguard Worker } else {
157*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS,
158*49cdfc7eSAndroid Build Coastguard Worker "Functionality of "
159*49cdfc7eSAndroid Build Coastguard Worker "sigaltstack() successful");
160*49cdfc7eSAndroid Build Coastguard Worker }
161*49cdfc7eSAndroid Build Coastguard Worker }
162*49cdfc7eSAndroid Build Coastguard Worker tst_count++; /* incr. TEST_LOOP counter */
163*49cdfc7eSAndroid Build Coastguard Worker }
164*49cdfc7eSAndroid Build Coastguard Worker
165*49cdfc7eSAndroid Build Coastguard Worker cleanup();
166*49cdfc7eSAndroid Build Coastguard Worker tst_exit();
167*49cdfc7eSAndroid Build Coastguard Worker }
168*49cdfc7eSAndroid Build Coastguard Worker
169*49cdfc7eSAndroid Build Coastguard Worker /*
170*49cdfc7eSAndroid Build Coastguard Worker * void
171*49cdfc7eSAndroid Build Coastguard Worker * setup() - performs all ONE TIME setup for this test.
172*49cdfc7eSAndroid Build Coastguard Worker * Capture SIGUSR1 on the main stack.
173*49cdfc7eSAndroid Build Coastguard Worker * send the signal 'SIGUSER1' to the process.
174*49cdfc7eSAndroid Build Coastguard Worker * wait till the signal arrives.
175*49cdfc7eSAndroid Build Coastguard Worker * Allocate memory for the alternative stack.
176*49cdfc7eSAndroid Build Coastguard Worker */
setup(void)177*49cdfc7eSAndroid Build Coastguard Worker void setup(void)
178*49cdfc7eSAndroid Build Coastguard Worker {
179*49cdfc7eSAndroid Build Coastguard Worker
180*49cdfc7eSAndroid Build Coastguard Worker tst_sig(FORK, DEF_HANDLER, cleanup);
181*49cdfc7eSAndroid Build Coastguard Worker
182*49cdfc7eSAndroid Build Coastguard Worker TEST_PAUSE;
183*49cdfc7eSAndroid Build Coastguard Worker
184*49cdfc7eSAndroid Build Coastguard Worker /* Get the process id of test process */
185*49cdfc7eSAndroid Build Coastguard Worker my_pid = getpid();
186*49cdfc7eSAndroid Build Coastguard Worker
187*49cdfc7eSAndroid Build Coastguard Worker /* Capture SIGUSR1 on the main stack */
188*49cdfc7eSAndroid Build Coastguard Worker act.sa_handler = (void (*)(int))sig_handler;
189*49cdfc7eSAndroid Build Coastguard Worker if ((sigaction(SIGUSR1, &act, &oact)) == -1) {
190*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TFAIL, cleanup,
191*49cdfc7eSAndroid Build Coastguard Worker "sigaction() fails in setup, errno=%d", errno);
192*49cdfc7eSAndroid Build Coastguard Worker }
193*49cdfc7eSAndroid Build Coastguard Worker
194*49cdfc7eSAndroid Build Coastguard Worker /* Send the signal to the test process */
195*49cdfc7eSAndroid Build Coastguard Worker kill(my_pid, SIGUSR1);
196*49cdfc7eSAndroid Build Coastguard Worker
197*49cdfc7eSAndroid Build Coastguard Worker /* Wait till the signal arrives */
198*49cdfc7eSAndroid Build Coastguard Worker while (!got_signal) ;
199*49cdfc7eSAndroid Build Coastguard Worker
200*49cdfc7eSAndroid Build Coastguard Worker got_signal = 0;
201*49cdfc7eSAndroid Build Coastguard Worker main_stk = addr;
202*49cdfc7eSAndroid Build Coastguard Worker
203*49cdfc7eSAndroid Build Coastguard Worker /* Allocate memory for the alternate stack */
204*49cdfc7eSAndroid Build Coastguard Worker if ((sigstk.ss_sp = malloc(SIGSTKSZ)) == NULL) {
205*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TFAIL, cleanup,
206*49cdfc7eSAndroid Build Coastguard Worker "could not allocate memory for the alternate stack");
207*49cdfc7eSAndroid Build Coastguard Worker }
208*49cdfc7eSAndroid Build Coastguard Worker }
209*49cdfc7eSAndroid Build Coastguard Worker
210*49cdfc7eSAndroid Build Coastguard Worker /*
211*49cdfc7eSAndroid Build Coastguard Worker * void
212*49cdfc7eSAndroid Build Coastguard Worker * sig_handler() - signal catching function.
213*49cdfc7eSAndroid Build Coastguard Worker * This functions is called when the signal 'SIGUSR1' is delivered to
214*49cdfc7eSAndroid Build Coastguard Worker * the test process and trapped by sigaction().
215*49cdfc7eSAndroid Build Coastguard Worker *
216*49cdfc7eSAndroid Build Coastguard Worker * This function updates 'addr' variable and sets got_signal value.
217*49cdfc7eSAndroid Build Coastguard Worker */
sig_handler(int n)218*49cdfc7eSAndroid Build Coastguard Worker void sig_handler(int n)
219*49cdfc7eSAndroid Build Coastguard Worker {
220*49cdfc7eSAndroid Build Coastguard Worker int i;
221*49cdfc7eSAndroid Build Coastguard Worker
222*49cdfc7eSAndroid Build Coastguard Worker (void) n;
223*49cdfc7eSAndroid Build Coastguard Worker addr = &i;
224*49cdfc7eSAndroid Build Coastguard Worker got_signal = 1;
225*49cdfc7eSAndroid Build Coastguard Worker }
226*49cdfc7eSAndroid Build Coastguard Worker
227*49cdfc7eSAndroid Build Coastguard Worker /*
228*49cdfc7eSAndroid Build Coastguard Worker * void
229*49cdfc7eSAndroid Build Coastguard Worker * cleanup() - performs all ONE TIME cleanup for this test at
230*49cdfc7eSAndroid Build Coastguard Worker * completion or premature exit.
231*49cdfc7eSAndroid Build Coastguard Worker * Free the memory allocated for alternate stack.
232*49cdfc7eSAndroid Build Coastguard Worker */
cleanup(void)233*49cdfc7eSAndroid Build Coastguard Worker void cleanup(void)
234*49cdfc7eSAndroid Build Coastguard Worker {
235*49cdfc7eSAndroid Build Coastguard Worker
236*49cdfc7eSAndroid Build Coastguard Worker free(sigstk.ss_sp);
237*49cdfc7eSAndroid Build Coastguard Worker
238*49cdfc7eSAndroid Build Coastguard Worker }
239