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_07 |
21 | ==================================================================== |
22 | |
23 | Description: Signal stress - send many signals to the process and |
24 | verify that it receives every one |
25 | |
26 | Algorithm: o Block all signals from interrupting the process |
27 | o Send MAX signals to the current process |
28 | o Sleep for a short time |
29 | o Verify that signals are pending |
30 | o Change the signal mask and suspend execution until |
31 | a signal interrupts the process |
32 | o Verify that at least one signal was received |
33 | |
34 | |
35 | System calls: The following system calls are tested: |
36 | |
37 | sigaction () - Specify the action to take upon |
38 | delivery of a signal |
39 | wait () - Waits for a child process to stop or |
40 | terminate |
41 | kill () - Sends a signal to a process |
42 | |
43 | Usage: signal_test_07 |
44 | |
45 | To compile: cc -o signal_test_07 signal_test_07 |
46 | |
47 | Last update: Ver. 1.3, 7/7/94 16:18:19 |
48 | |
49 | Change Activity |
50 | |
51 | Version Date Name Reason |
52 | 0.1 050689 CTU Initial version |
53 | 0.2 112993 DJK Rewrite for AIX version 4.1 |
54 | 1.2 020794 DJK Move to "prod" directory |
55 | |
56 +---------------------------------------------------------------------*/
57
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #include <unistd.h>
62 #include <sys/signal.h>
63 #include <sys/wait.h>
64 #include <errno.h>
65
66 #ifdef _LINUX_
67 // bits/signum.h defines _NSIG as 64
68 #define SIGMAX 64
69 #endif
70
71 /* Function prototypes */
72 void handler(int, int, struct sigcontext *);
73 void init_sig();
74 void sys_error(const char *, int);
75 void error(const char *, int);
76
77 int signals_received = 0;
78
79 #define MAXSIG 1024*1024 /* Max interrupts */
80 #define MAXTIME 2 /* Time out (minutes) */
81
82 /*---------------------------------------------------------------------+
83 | main () |
84 | ==================================================================== |
85 | |
86 | Function: Main program (see prolog for more details) |
87 | |
88 +---------------------------------------------------------------------*/
main(int argc,char ** argv)89 int main(int argc, char **argv)
90 {
91 int timeout = MAXTIME * 60; /* Timeout value */
92 int i; /* Loop index */
93 char msg[256]; /* Buffer for error message */
94
95 /* Print out program header */
96 printf("%s: IPC TestSuite program\n\n", *argv);
97 fflush(stdout);
98
99 /* Set up our signal handler */
100 init_sig();
101
102 /*
103 * Send MAXSIG signals to the process
104 *
105 * Using raise, send MAX signals to the process. Then loop until
106 * every signal is caught by the signal handler (or the timer expires).
107 */
108 printf("\tSend MAX (%d) signals to the process...\n", MAXSIG);
109 fflush(stdout);
110 for (i = 0; i < MAXSIG; i++)
111 raise(SIGUSR1);
112
113 while (signals_received < MAXSIG && --timeout)
114 sleep(1);
115
116 if (timeout == 0) {
117 sprintf(msg, "failed to received %d signals in %d minutes\n",
118 MAXSIG, MAXTIME);
119 error(msg, __LINE__);
120 }
121
122 /*
123 * Received ALL of the sent signals! Exit with success
124 */
125 printf("\n\tReceived EVERY signal!\n");
126
127 printf("\nsuccessful!\n");
128 return (0);
129 }
130
131 /*---------------------------------------------------------------------+
132 | handler () |
133 | ==================================================================== |
134 | |
135 | Function: Signal handler |
136 | |
137 | Parms: signal - signal number caught |
138 | |
139 | Returns: Aborts if an unexpected signal is caught |
140 | |
141 +---------------------------------------------------------------------*/
handler(int signal,int code,struct sigcontext * scp)142 void handler(int signal, int code, struct sigcontext *scp)
143 {
144 char msg[256]; /* Buffer for error message */
145
146 if (signal == SIGUSR1) {
147 signals_received++;
148 } else if (signal == SIGUSR2) {
149 printf("\tcaught signal (%d)\n", signal);
150 } else {
151 sprintf(msg, "caught an unexpected signal (%d)", signal);
152 error(msg, __LINE__);
153 }
154 }
155
156 /*---------------------------------------------------------------------+
157 | init_sig () |
158 | ==================================================================== |
159 | |
160 | Function: Initialize the signal vector for ALL possible signals |
161 | (as defined in /usr/include/sys/signal.h) except for |
162 | the following signals which cannot be caught or ignored: |
163 | |
164 | o SIGKILL (9) |
165 | o SIGSTOP (17) |
166 | o SIGCONT (19) |
167 | |
168 | Returns: n/a |
169 | |
170 +---------------------------------------------------------------------*/
init_sig()171 void init_sig()
172 {
173 struct sigaction invec;
174 char msg[256]; /* Buffer for error message */
175 int i;
176
177 for (i = 1; i <= SIGMAX; i++) {
178
179 /* Cannot catch or ignore the following signals */
180 #ifdef _IA64 /* SIGWAITING not supported, RESERVED */
181 if ((i == SIGKILL) || (i == SIGSTOP) ||
182 (i == SIGCONT) || (i == SIGWAITING))
183 continue;
184 #else
185 #ifdef _LINUX_
186 if ((i == SIGKILL) || (i == SIGSTOP)
187 || ((i >= 32) && (i <= 34)))
188 continue;
189 #else
190 if (i == SIGKILL || i == SIGSTOP || i == SIGCONT)
191 continue;
192 #endif
193 #endif
194
195 invec.sa_handler = (void (*)(int))handler;
196 sigemptyset(&invec.sa_mask);
197 invec.sa_flags = 0;
198
199 if (sigaction(i, &invec, NULL) < 0) {
200 sprintf(msg, "sigaction failed on signal %d", i);
201 error(msg, __LINE__);
202 }
203 }
204 }
205
206 /*---------------------------------------------------------------------+
207 | sys_error () |
208 | ==================================================================== |
209 | |
210 | Function: Creates system error message and calls error () |
211 | |
212 +---------------------------------------------------------------------*/
sys_error(const char * msg,int line)213 void sys_error(const char *msg, int line)
214 {
215 char syserr_msg[256];
216
217 sprintf(syserr_msg, "%s: %s\n", msg, strerror(errno));
218 error(syserr_msg, line);
219 }
220
221 /*---------------------------------------------------------------------+
222 | error () |
223 | ==================================================================== |
224 | |
225 | Function: Prints out message and exits... |
226 | |
227 +---------------------------------------------------------------------*/
error(const char * msg,int line)228 void error(const char *msg, int line)
229 {
230 fprintf(stderr, "ERROR [line: %d] %s\n", line, msg);
231 exit(-1);
232 }
233