1/******************************************************************************/
2/* Copyright (c) Crackerjack Project., 2007                                   */
3/*                                                                            */
4/* This program is free software;  you can redistribute it and/or modify      */
5/* it under the terms of the GNU General Public License as published by       */
6/* the Free Software Foundation; either version 2 of the License, or          */
7/* (at your option) any later version.                                        */
8/*                                                                            */
9/* This program is distributed in the hope that it will be useful,            */
10/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            */
11/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  */
12/* the GNU General Public License for more details.                           */
13/*                                                                            */
14/* You should have received a copy of the GNU General Public License          */
15/* along with this program;  if not, write to the Free Software Foundation,   */
16/* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA           */
17/*                                                                            */
18/* History:     Porting from Crackerjack to LTP is done by                    */
19/*              Manas Kumar Nayak maknayak@in.ibm.com>                        */
20/******************************************************************************/
21
22/******************************************************************************/
23/* Description: This tests the rt_sigaction() syscall                         */
24/*		rt_sigaction Expected EINVAL error check                      */
25/******************************************************************************/
26
27#define _GNU_SOURCE
28#include <stdio.h>
29#include <stdlib.h>
30#include <unistd.h>
31#include <signal.h>
32#include <errno.h>
33#include <sys/syscall.h>
34#include <string.h>
35
36#include "test.h"
37#include "lapi/syscalls.h"
38#include "lapi/rt_sigaction.h"
39
40#define INVAL_SIGSETSIZE -1
41
42char *TCID = "rt_sigaction03";
43static int testno;
44int TST_TOTAL = 1;
45
46static void cleanup(void)
47{
48	tst_rmdir();
49}
50
51static void setup(void)
52{
53	TEST_PAUSE;
54	tst_tmpdir();
55}
56
57static int test_flags[] =
58    { SA_RESETHAND | SA_SIGINFO, SA_RESETHAND, SA_RESETHAND | SA_SIGINFO,
59SA_RESETHAND | SA_SIGINFO, SA_NOMASK };
60char *test_flags_list[] =
61    { "SA_RESETHAND|SA_SIGINFO", "SA_RESETHAND", "SA_RESETHAND|SA_SIGINFO",
62"SA_RESETHAND|SA_SIGINFO", "SA_NOMASK" };
63
64static struct test_case_t {
65	int exp_errno;
66	char *errdesc;
67} test_cases[] = {
68	{
69	EINVAL, "EINVAL"}
70};
71
72static void handler(int sig)
73{
74	tst_resm(TINFO, "Signal Handler Called with signal number %d", sig);
75	return;
76}
77
78static int set_handler(int sig, int sig_to_mask, int mask_flags)
79{
80	struct sigaction sa, oldaction;
81
82	sa.sa_sigaction = (void *)handler;
83	sa.sa_flags = mask_flags;
84	sigemptyset(&sa.sa_mask);
85	sigaddset(&sa.sa_mask, sig_to_mask);
86
87	/*                                                              *
88	 * long sys_rt_sigaction (int sig, const struct sigaction *act, *
89	 * truct sigaction *oact, size_t sigsetsize);                   *
90	 * EINVAL:                                                      *
91	 * sigsetsize was not equivalent to the size of a sigset_t type *
92	 */
93
94	return ltp_rt_sigaction(sig, &sa, &oldaction, INVAL_SIGSETSIZE);
95}
96
97int main(int ac, char **av)
98{
99	unsigned int flag;
100	int signal;
101	int lc;
102
103	tst_parse_opts(ac, av, NULL, NULL);
104
105	setup();
106
107	for (lc = 0; TEST_LOOPING(lc); ++lc) {
108		tst_count = 0;
109		for (testno = 0; testno < TST_TOTAL; ++testno) {
110
111			for (signal = SIGRTMIN; signal <= (SIGRTMAX); signal++) {
112				tst_resm(TINFO, "Signal %d", signal);
113
114				for (flag = 0; flag < ARRAY_SIZE(test_flags); flag++) {
115					TEST(set_handler
116					     (signal, 0, test_flags[flag]));
117					if ((TEST_RETURN == -1)
118					    && (TEST_ERRNO ==
119						test_cases[0].exp_errno)) {
120						tst_resm(TINFO,
121							 "sa.sa_flags = %s ",
122							 test_flags_list[flag]);
123						tst_resm(TPASS,
124							 "%s failure with sig: %d as expected errno  = %s : %s",
125							 TCID, signal,
126							 test_cases[0].errdesc,
127							 strerror(TEST_ERRNO));
128					} else {
129						tst_resm(TFAIL,
130							 "rt_sigaction call succeeded: result = %ld got error %d:but expected  %d",
131							 TEST_RETURN,
132							 TEST_ERRNO,
133							 test_cases[0].
134							 exp_errno);
135						tst_resm(TINFO,
136							 "sa.sa_flags = %s ",
137							 test_flags_list[flag]);
138					}
139				}
140			}
141
142		}
143	}
144	cleanup();
145	tst_exit();
146}
147