1 /*
2 * Copyright (C) Bull S.A. 1996
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 | signal_test_03 |
21 | ==================================================================== |
22 | |
23 | Description: Block a critical section from receiving signals. |
24 | |
25 | Algorithm: o Setup a signal-catching function |
26 | o Beginning of Critical section -- Set the process |
27 | signal mask to block the SIGILL signal |
28 | o Send SIGILL signal to the process to insure that |
29 | the signal is blocked during the critical section |
30 | o Preform the critical section code (merely sleep |
31 | for testing purposes) |
32 | o Verify that the signal was blocked |
33 | o End of Critical section -- unblock the signal and |
34 | suspend he process signal mask to unblock one |
35 | signal and suspend execution of the process until |
36 | the signal is received. Verify that the unblocked |
37 | signal is received. |
38 | |
39 | System calls: The following system calls are tested: |
40 | |
41 | sigsetmask () - Sets the current signal mask |
42 | sigblock () - Sets the current signal mask |
43 | sigvec () - Specify the action to take upon delivery |
44 | of a signal. |
45 | raise () - Sends a signal to the executing program |
46 | |
47 | Usage: signal_test_03 |
48 | |
49 | To compile: cc -o signal_test_03 signal_test_03 |
50 | |
51 | Last update: Ver. 1.2, 2/7/94 23:23:34 |
52 | |
53 | Change Activity |
54 | |
55 | Version Date Name Reason |
56 | 0.1 050689 CTU Initial version |
57 | 1.2 112293 DJK Rewrite for AIX version 4.1 |
58 | |
59 +---------------------------------------------------------------------*/
60
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <signal.h>
64 #include <string.h>
65 #include <unistd.h>
66 #include <errno.h>
67
68 #define MASK(sig) (1 << ((sig) - 1))
69 #define MAXTIME 2 /* MAX timeout (minutes) */
70
71 #ifdef _LINUX_
72 // bits/signum.h defines _NSIG as 64
73 #define SIGMAX 64
74 #endif
75
76 #include "signals.h"
77
78 /* Function prototypes */
79 void handler(int);
80 void init_sig_vec();
81 void sys_error(const char *, int);
82 void error(const char *, int);
83
84 /* Global variables */
85 int signals_received = 0;
86
87 /*---------------------------------------------------------------------+
88 | main () |
89 | ==================================================================== |
90 | |
91 | Function: Main program (see prolog for more details) |
92 | |
93 +---------------------------------------------------------------------*/
main(int argc,char ** argv)94 int main(int argc, char **argv)
95 {
96 int timeout = MAXTIME * 60; /* Number sec to wait for signal */
97
98 /* Print out program header */
99 printf("%s: IPC Signals TestSuite program\n\n", *argv);
100
101 /* Set up our signal handlers */
102 init_sig_vec();
103
104 /*
105 * Critical section - block SIGILL signal
106 *
107 * Block the SIGILL interrupt from interrupting the process
108 * with the sigprocmask () system function call.
109 *
110 * Send the SIGILL interrupt to the process in an attempt to
111 * disrupt the critial section -- the signal should be blocked.
112 * Wait one second to insure that the signal has plenty of time
113 * to reach the process.
114 */
115 #ifdef _LINUX_
116 sigset_t mask;
117 sigemptyset(&mask);
118 sigaddset(&mask, SIGILL);
119 sigprocmask(SIG_BLOCK, &mask, NULL);
120 #else
121 if (sigblock(MASK(SIGILL)) < 0)
122 sys_error("sigblock failed", __LINE__);
123 #endif
124
125 printf("\t(BEGIN) Critial section\n");
126
127 /* Critial section */
128 sleep(1);
129
130 /*
131 * End of critical section - ensure SIGILL signal was not received
132 *
133 * Check to insure that the signal handler has not caught any signals,
134 * and then unblock all of the signals with the sigsetmask system
135 * function call.
136 */
137 if (signals_received > 0)
138 error
139 ("received an unexpected signal during the critical section",
140 __LINE__);
141
142 printf("\n\t(END) Critial section\n");
143
144 #ifdef _LINUX_
145 sigemptyset(&mask);
146 sigprocmask(SIG_SETMASK, &mask, NULL);
147 #else
148 if (sigsetmask(0) < 0)
149 sys_error("sigsetmask failed", __LINE__);
150 #endif
151 raise(SIGILL);
152
153 /*
154 * Upon unblocking the signals, should receive the SIGILL signal.
155 * Verify that it indeed is caught.
156 */
157 while (signals_received == 0 && --timeout) {
158 printf(".");
159 fflush(stdout);
160 sleep(1);
161 }
162
163 if (timeout == 0)
164 error
165 ("failed to receive SIGILL signal after unblocking signals",
166 __LINE__);
167
168 /* Program completed successfully -- exit */
169 printf("\nsuccessful!\n");
170 return (0);
171 }
172
173 /*---------------------------------------------------------------------+
174 | init_sig_vec () |
175 | ==================================================================== |
176 | |
177 | Function: Initialize the signal vector for ALL possible signals |
178 | (as defined in /usr/include/sys/signal.h) except for |
179 | the following signals which cannot be caught or ignored: |
180 | |
181 | o SIGKILL (9) |
182 | o SIGSTOP (17) |
183 | o SIGCONT (19) |
184 | |
185 | Returns: Nothing |
186 | |
187 +---------------------------------------------------------------------*/
init_sig_vec()188 void init_sig_vec()
189 {
190 struct sigaction invec;
191 char msg[256]; /* Buffer for error message */
192 int i;
193
194 for (i = 1; i <= SIGMAX; i++) {
195
196 /* Cannot catch or ignore the following signals */
197 #ifdef _IA64 /* SIGWAITING not supported, RESERVED */
198 if ((i == SIGKILL) || (i == SIGSTOP) ||
199 (i == SIGCONT) || (i == SIGWAITING))
200 continue;
201 #else
202 #ifdef _LINUX_
203 if ((i == SIGKILL) || (i == SIGSTOP)
204 || ((i >= 32) && (i <= 34)))
205 continue;
206 #else
207 if (i == SIGKILL || i == SIGSTOP || i == SIGCONT)
208 continue;
209 #endif
210 #endif
211
212 invec.sa_handler = (void (*)(int))handler;
213 sigemptyset(&invec.sa_mask);
214 invec.sa_flags = 0;
215
216 if (sigaction(i, &invec, NULL) < 0) {
217 sprintf(msg, "sigaction failed on signal %d", i);
218 error(msg, __LINE__);
219 }
220 }
221 }
222
223 /*---------------------------------------------------------------------+
224 | handler () |
225 | ==================================================================== |
226 | |
227 | Function: Signal catching function. This function is called each |
228 | time a non-blocked signal is received by the process. |
229 | |
230 | Increment the global variable (signals_received) for |
231 | each received signal. |
232 | |
233 | Returns: Nothing |
234 | |
235 +---------------------------------------------------------------------*/
handler(int signal)236 void handler(int signal)
237 {
238 if (signal == SIGILL)
239 signals_received++;
240 printf("\treceived signal: (%s)\n", signames[signal]);
241 }
242
243 /*---------------------------------------------------------------------+
244 | sys_error () |
245 | ==================================================================== |
246 | |
247 | Function: Creates system error message and calls error () |
248 | |
249 +---------------------------------------------------------------------*/
sys_error(const char * msg,int line)250 void sys_error(const char *msg, int line)
251 {
252 char syserr_msg[256];
253
254 sprintf(syserr_msg, "%s: %s\n", msg, strerror(errno));
255 error(syserr_msg, line);
256 }
257
258 /*---------------------------------------------------------------------+
259 | error () |
260 | ==================================================================== |
261 | |
262 | Function: Prints out message and exits... |
263 | |
264 +---------------------------------------------------------------------*/
error(const char * msg,int line)265 void error(const char *msg, int line)
266 {
267 fprintf(stderr, "ERROR [line: %d] %s\n", line, msg);
268 exit(-1);
269 }
270