Home | History | Annotate | Download | only in sigaltstack
      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 
    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  */
    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  */
    186 void cleanup(void)
    187 {
    188 
    189 	free(sigstk.ss_sp);
    190 
    191 }
    192