1/*
2* Copyright (c) 2005, Bull S.A..  All rights reserved.
3* Created by: Sebastien Decugis
4
5* This program is free software; you can redistribute it and/or modify it
6* under the terms of version 2 of the GNU General Public License as
7* published by the Free Software Foundation.
8*
9* This program is distributed in the hope that it would be useful, but
10* WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*
13* You should have received a copy of the GNU General Public License along
14* with this program; if not, write the Free Software Foundation, Inc.,
15* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17* This sample test aims to check the following assertions:
18*
19* sigaction returns -1 and errno is set to EINVAL if signal number is invalid
20* or an attempt to do an operation which is not allowed is made.
21
22* The steps are:
23* -> Try setting a signal handler for signal SIGRTMAX + 1
24* -> Try setting a signal handler for SIGKILL
25* -> Try setting a signal handler for SIGSTOP
26* -> Try ignoring SIGSTOP
27* -> Try ignoring SIGKILL
28
29* The test fails if the signals are not delivered in FIFO order.
30*/
31
32/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
33#define _POSIX_C_SOURCE 200112L
34
35/******************************************************************************/
36/*************************** standard includes ********************************/
37/******************************************************************************/
38#include <pthread.h>
39#include <stdarg.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44
45#include <signal.h>
46#include <errno.h>
47
48/******************************************************************************/
49/***************************   Test framework   *******************************/
50/******************************************************************************/
51#include "../testfrmw/testfrmw.h"
52#include "../testfrmw/testfrmw.c"
53/* This header is responsible for defining the following macros:
54 * UNRESOLVED(ret, descr);
55 *    where descr is a description of the error and ret is an int
56 *   (error code for example)
57 * FAILED(descr);
58 *    where descr is a short text saying why the test has failed.
59 * PASSED();
60 *    No parameter.
61 *
62 * Both three macros shall terminate the calling process.
63 * The testcase shall not terminate in any other maneer.
64 *
65 * The other file defines the functions
66 * void output_init()
67 * void output(char * string, ...)
68 *
69 * Those may be used to output information.
70 */
71
72/******************************************************************************/
73/**************************** Configuration ***********************************/
74/******************************************************************************/
75#ifndef VERBOSE
76#define VERBOSE 1
77#endif
78
79#define SIG_INVALID SIGRTMAX+10
80
81/******************************************************************************/
82/***************************    Test case   ***********************************/
83/******************************************************************************/
84
85void handler(int signo)
86{
87	return;
88}
89
90/* main function */
91int main(void)
92{
93	int ret;
94
95	struct sigaction sa;
96
97	/* Initialize output */
98	output_init();
99
100	/* Set the signal handler */
101	sa.sa_flags = 0;
102
103	sa.sa_handler = handler;
104
105	ret = sigemptyset(&sa.sa_mask);
106
107	if (ret != 0) {
108		UNRESOLVED(ret, "Failed to empty signal set");
109	}
110
111	/* Install the signal handler for SIGRTMAX */
112#if VERBOSE > 0
113	output("Trying to catch invalid signal %d\n", SIG_INVALID);
114
115#endif
116	ret = sigaction(SIG_INVALID, &sa, 0);
117
118	if (ret == 0) {
119		output("Is signal %d valid on this implementation?\n",
120		       SIG_INVALID);
121		FAILED("Setting handler for invalid signal did not fail");
122	}
123
124	if (errno != EINVAL) {
125		output("Got error %d (%s) instead of %d (%s)\n",
126		       errno, strerror(errno), EINVAL, strerror(EINVAL));
127		FAILED("Wrong error code returned");
128	}
129
130	/* Install the signal handler for SIGKILL */
131#if VERBOSE > 0
132	output("Trying to catch unauthorized signal SIGKILL (%d)\n", SIGKILL);
133
134#endif
135	ret = sigaction(SIGKILL, &sa, 0);
136
137	if (ret == 0) {
138		FAILED("Setting handler for SIGKILL did not fail");
139	}
140
141	if (errno != EINVAL) {
142		output("Got error %d (%s) instead of %d (%s)\n",
143		       errno, strerror(errno), EINVAL, strerror(EINVAL));
144		FAILED("Wrong error code returned");
145	}
146
147	/* Install the signal handler for SIGSTOP */
148#if VERBOSE > 0
149	output("Trying to catch unauthorized signal SIGSTOP (%d)\n", SIGSTOP);
150
151#endif
152	ret = sigaction(SIGSTOP, &sa, 0);
153
154	if (ret == 0) {
155		FAILED("Setting handler for SIGSTOP did not fail");
156	}
157
158	if (errno != EINVAL) {
159		output("Got error %d (%s) instead of %d (%s)\n",
160		       errno, strerror(errno), EINVAL, strerror(EINVAL));
161		FAILED("Wrong error code returned");
162	}
163
164	sa.sa_handler = SIG_IGN;
165
166	/* Ingrore SIGKILL */
167#if VERBOSE > 0
168	output("Trying to ignore unauthorized signal SIGKILL (%d)\n", SIGKILL);
169
170#endif
171	ret = sigaction(SIGKILL, &sa, 0);
172
173	if (ret == 0) {
174		FAILED("Ignoring SIGKILL did not fail");
175	}
176
177	if (errno != EINVAL) {
178		output("Got error %d (%s) instead of %d (%s)\n",
179		       errno, strerror(errno), EINVAL, strerror(EINVAL));
180		FAILED("Wrong error code returned");
181	}
182
183	/* Ignore SIGSTOP */
184#if VERBOSE > 0
185	output("Trying to ignore unauthorized signal SIGSTOP (%d)\n", SIGSTOP);
186
187#endif
188	ret = sigaction(SIGSTOP, &sa, 0);
189
190	if (ret == 0) {
191		FAILED("Ignoring SIGSTOP did not fail");
192	}
193
194	if (errno != EINVAL) {
195		output("Got error %d (%s) instead of %d (%s)\n",
196		       errno, strerror(errno), EINVAL, strerror(EINVAL));
197		FAILED("Wrong error code returned");
198	}
199
200	/* Test passed */
201#if VERBOSE > 0
202
203	output("Test passed\n");
204
205#endif
206
207	PASSED;
208}
209