• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /*
21  * Test Name: sigalstack02
22  *
23  * Test Description:
24  *  Verify that,
25  *   1. sigaltstack() fails and sets errno to EINVAL when "ss_flags" field
26  *      pointed to by 'ss' contains invalid flags.
27  *   2. sigaltstack() fails and sets errno to ENOMEM when the size of alternate
28  *      stack area is less than MINSIGSTKSZ.
29  *
30  * Expected Result:
31  *  sigaltstack() should fail with return value -1 and set expected errno.
32  *
33  * Algorithm:
34  *  Setup:
35  *   Setup signal handling.
36  *   Create temporary directory.
37  *   Pause for SIGUSR1 if option specified.
38  *
39  *  Test:
40  *   Loop if the proper options are given.
41  *   Execute system call
42  *   Check return code, if system call failed (return=-1)
43  *	if errno set == expected errno
44  *		Issue sys call fails with expected return value and errno.
45  *	Otherwise,
46  *		Issue sys call fails with unexpected errno.
47  *   Otherwise,
48  *	Issue sys call returns unexpected value.
49  *
50  *  Cleanup:
51  *   Print errno log and/or timing stats if options given
52  *   Delete the temporary directory(s)/file(s) created.
53  *
54  * Usage:  <for command-line>
55  *  sigaltstack02 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
56  *	where,  -c n : Run n copies concurrently.
57  *		-e   : Turn on errno logging.
58  *		-f   : Turn off functionality Testing.
59  *		-i n : Execute test n times.
60  *		-I x : Execute test for x seconds.
61  *		-P x : Pause for x seconds between iterations.
62  *		-t   : Turn on syscall timing.
63  *
64  * History
65  *	07/2001 John George
66  *		-Ported
67  *
68  * Restrictions:
69  *  This test should be executed by super-user (root) only.
70  */
71 
72 #include <stdio.h>
73 #include <sys/types.h>
74 #include <unistd.h>
75 #include <signal.h>
76 #include <string.h>
77 #include <ucontext.h>
78 #include <errno.h>
79 
80 #include "test.h"
81 
82 #define INVAL_FLAGS	9999
83 
84 char *TCID = "sigaltstack02";
85 int TST_TOTAL = 2;
86 
87 stack_t sigstk;			/* signal stack storing struct. */
88 
89 void setup(void);			/* Main setup function of test */
90 void cleanup(void);			/* cleanup function for the test */
91 
92 struct test_case_t {		/* test case struct. to hold diff. test.conds */
93 	int flag;
94 	int size;
95 	char *desc;
96 	int exp_errno;
97 } Test_cases[] = {
98 	{
99 	INVAL_FLAGS, SIGSTKSZ, "Invalid Flag value", EINVAL},
100 	/* use value low enough for all kernel versions
101 	 * avoid using MINSIGSTKSZ defined by glibc as it could be different
102 	 * from the one in kernel ABI
103 	 */
104 	{
105 	0, (2048 - 1), "alternate stack is < MINSIGSTKSZ", ENOMEM},
106 	{
107 	0, 0, NULL, 0}
108 };
109 
main(int ac,char ** av)110 int main(int ac, char **av)
111 {
112 	int lc;
113 	char *test_desc;	/* test specific error message */
114 	int ind;		/* counter to test different test conditions */
115 
116 	tst_parse_opts(ac, av, NULL, NULL);
117 
118 	setup();
119 
120 	for (lc = 0; TEST_LOOPING(lc); lc++) {
121 
122 		tst_count = 0;
123 
124 		for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
125 			sigstk.ss_size = Test_cases[ind].size;
126 			sigstk.ss_flags = Test_cases[ind].flag;
127 			test_desc = Test_cases[ind].desc;
128 
129 			/* Verify sigaltstack() fails and sets errno */
130 			TEST(sigaltstack(&sigstk, NULL));
131 
132 			/* Check return code from sigaltstack() */
133 			if (TEST_RETURN == -1) {
134 				if (TEST_ERRNO ==
135 				    Test_cases[ind].exp_errno) {
136 					tst_resm(TPASS, "stgaltstack() "
137 						 "fails, %s, errno:%d",
138 						 test_desc, TEST_ERRNO);
139 				} else {
140 					tst_resm(TFAIL, "sigaltstack() "
141 						 "fails, %s, errno:%d, "
142 						 "expected errno:%d",
143 						 test_desc, TEST_ERRNO,
144 						 Test_cases
145 						 [ind].exp_errno);
146 				}
147 			} else {
148 				tst_resm(TFAIL, "sigaltstack() returned %ld, "
149 					 "expected -1, errno:%d", TEST_RETURN,
150 					 Test_cases[ind].exp_errno);
151 			}
152 		}
153 		tst_count++;	/* incr. TEST_LOOP counter */
154 	}
155 
156 	cleanup();
157 	tst_exit();
158 
159 }
160 
161 /*
162  * void
163  * setup() - performs all ONE TIME setup for this test.
164  * Allocate memory for the alternative stack.
165  */
setup(void)166 void setup(void)
167 {
168 
169 	tst_sig(FORK, DEF_HANDLER, cleanup);
170 
171 	TEST_PAUSE;
172 
173 	/* Allocate memory for the alternate stack */
174 	if ((sigstk.ss_sp = malloc(SIGSTKSZ)) == NULL) {
175 		tst_brkm(TFAIL, cleanup,
176 			 "could not allocate memory for the alternate stack");
177 	}
178 }
179 
180 /*
181  * void
182  * cleanup() - performs all ONE TIME cleanup for this test at
183  *             completion or premature exit.
184  *  Free the memory allocated for alternate stack.
185  */
cleanup(void)186 void cleanup(void)
187 {
188 
189 	free(sigstk.ss_sp);
190 
191 }
192