xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/sigaltstack/sigaltstack01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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