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#include <stdio.h>
28#include <stdlib.h>
29#include <unistd.h>
30#include <signal.h>
31#include <errno.h>
32#include <sys/syscall.h>
33#include <string.h>
34
35#include "test.h"
36#include "linux_syscall_numbers.h"
37#include "lapi/rt_sigaction.h"
38
39#define INVAL_SIGSETSIZE -1
40
41char *TCID = "rt_sigaction03";
42static int testno;
43int TST_TOTAL = 1;
44
45static void cleanup(void)
46{
47	tst_rmdir();
48}
49
50static void setup(void)
51{
52	TEST_PAUSE;
53	tst_tmpdir();
54}
55
56static int test_flags[] =
57    { SA_RESETHAND | SA_SIGINFO, SA_RESETHAND, SA_RESETHAND | SA_SIGINFO,
58SA_RESETHAND | SA_SIGINFO, SA_NOMASK };
59char *test_flags_list[] =
60    { "SA_RESETHAND|SA_SIGINFO", "SA_RESETHAND", "SA_RESETHAND|SA_SIGINFO",
61"SA_RESETHAND|SA_SIGINFO", "SA_NOMASK" };
62
63static struct test_case_t {
64	int exp_errno;
65	char *errdesc;
66} test_cases[] = {
67	{
68	EINVAL, "EINVAL"}
69};
70
71static void handler(int sig)
72{
73	tst_resm(TINFO, "Signal Handler Called with signal number %d\n", sig);
74	return;
75}
76
77static int set_handler(int sig, int sig_to_mask, int mask_flags)
78{
79	struct sigaction sa, oldaction;
80
81	sa.sa_sigaction = (void *)handler;
82	sa.sa_flags = mask_flags;
83	sigemptyset(&sa.sa_mask);
84	sigaddset(&sa.sa_mask, sig_to_mask);
85
86	/*                                                              *
87	 * long sys_rt_sigaction (int sig, const struct sigaction *act, *
88	 * truct sigaction *oact, size_t sigsetsize);                   *
89	 * EINVAL:                                                      *
90	 * sigsetsize was not equivalent to the size of a sigset_t type *
91	 */
92
93	return ltp_rt_sigaction(sig, &sa, &oldaction, INVAL_SIGSETSIZE);
94}
95
96int main(int ac, char **av)
97{
98	unsigned int flag;
99	int signal;
100	int lc;
101
102	tst_parse_opts(ac, av, NULL, NULL);
103
104	setup();
105
106	for (lc = 0; TEST_LOOPING(lc); ++lc) {
107		tst_count = 0;
108		for (testno = 0; testno < TST_TOTAL; ++testno) {
109
110			for (signal = SIGRTMIN; signal <= (SIGRTMAX); signal++) {
111				tst_resm(TINFO, "Signal %d", signal);
112
113				for (flag = 0; flag < ARRAY_SIZE(test_flags); flag++) {
114					TEST(set_handler
115					     (signal, 0, test_flags[flag]));
116					if ((TEST_RETURN == -1)
117					    && (TEST_ERRNO ==
118						test_cases[0].exp_errno)) {
119						tst_resm(TINFO,
120							 "sa.sa_flags = %s ",
121							 test_flags_list[flag]);
122						tst_resm(TPASS,
123							 "%s failure with sig: %d as expected errno  = %s : %s",
124							 TCID, signal,
125							 test_cases[0].errdesc,
126							 strerror(TEST_ERRNO));
127					} else {
128						tst_resm(TFAIL,
129							 "rt_sigaction call succeeded: result = %ld got error %d:but expected  %d",
130							 TEST_RETURN,
131							 TEST_ERRNO,
132							 test_cases[0].
133							 exp_errno);
134						tst_resm(TINFO,
135							 "sa.sa_flags = %s ",
136							 test_flags_list[flag]);
137					}
138				}
139			}
140
141		}
142	}
143	cleanup();
144	tst_exit();
145}
146