signal_test_02.c revision ec6edca7aa42b6affd989ef91b5897f96795e40f
1d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*
2450ff20648579497cb788007438625aa74518d20subrata_modak *   Copyright (C) Bull S.A. 1996
3d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   Copyright (c) International Business Machines  Corp., 2001
4d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
5d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   This program is free software;  you can redistribute it and/or modify
6d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   it under the terms of the GNU General Public License as published by
7d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   the Free Software Foundation; either version 2 of the License, or
8d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   (at your option) any later version.
9d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
10d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   This program is distributed in the hope that it will be useful,
11d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   the GNU General Public License for more details.
14d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *
15d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   You should have received a copy of the GNU General Public License
16d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   along with this program;  if not, write to the Free Software
17d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj */
19d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
201be1c0c2f28892ffed0d2fcd34e551204060e22drobbiew|                          signal_test_02                              |
21d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
22d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
23d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Description:  Simplistic test to verify the signal system function   |
24d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               calls:                                                 |
25d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
26d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  Setup a signal-catching function for every possible |
27d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  signal.                                             |
28d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  Send signals to the process and verify that they    |
29d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  were received by the signal-catching function.      |
30d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  Block a few signals by changing the process signal  |
31d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  mask.  Send signals to the process and verify that  |
32d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  they indeed were blocked.                           |
33d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  Add additional signals to the process signal mask.  |
34d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  Verify that they were blocked too.                  |
35d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               o  Change the process signal mask to unblock one       |
36d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  signal and suspend execution of the process until   |
37d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  the signal is received.  Verify that the unblocked  |
38d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                  signal is received.                                 |
39d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
40d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| System calls: The following system calls are tested:                 |
41d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
42d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               sigprocmask () - Sets the current signal mask          |
43d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               sigemptyset () - Creates and manipulates signal masks  |
44d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               sigfillset () - Creates and manipulates signal masks   |
45d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               sigaddset () - Creates and manipulates signal masks    |
46d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               sigdelset () - Creates and manipulates signal masks    |
47d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               sigsuspend () - Atomically changes the set of blocked  |
48d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                               signals and waits for a signal         |
49d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               sigaction () - Specifies the action to take upon       |
50d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                              delivery of a signal                    |
51d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|               kill () - Sends a signal to a process                  |
52d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
53d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Usage:        signal_test_03                                         |
54d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
55d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| To compile:   cc -o signal_test_03 signal_test_03                    |
56d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
57d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Last update:   Ver. 1.2, 2/7/94 23:17:48                             |
58d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
59d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Change Activity                                                      |
60d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
61d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|   Version  Date    Name  Reason                                      |
62d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|    0.1     050689  CTU   Initial version                             |
63d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|    0.2     112293  DJK   Rewrite for AIX version 4.1                 |
64d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|    1.2     020794  DJK   Move to "prod" directory                    |
65d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|    1.3     060501  VHM   Port to work in linux                       |
66d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
67d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
68d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
69d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#define SIGMAX 64 /* What should this number really be? _NSIG from bits/signum.h maybe? */
70d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
71d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <stdio.h>
72045fd16a63837924a0f20d2419fbd497f8e36764robbiew#include <stdlib.h>
73d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <errno.h>
74d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <signal.h>
75f3a83d59cce260ab513313b2c43c41fc16983959robbiew#include <string.h>
76d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <unistd.h>
77d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include <sys/types.h>
78d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
79d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/* Macro for specifying signal masks */
80d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#define MASK(sig)  (1 << ((sig) - 1))
81d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
82d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#include "signals.h"
83d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
84d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/* Function prototypes */
85d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid init_sig ();
86d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid handler (int sig);//, int code, struct sigcontext *);
87d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid reset_valid_sig ();
88d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid sys_error (const char *, int);
89d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid error (const char *, int);
90d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
91d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/* Define an array for verifying received signals */
92d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint valid_sig [ SIGMAX + 1 ];
93d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
94d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
95d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                               main ()                                |
96d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
97d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
98d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Main program  (see prolog for more details)               |
99d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
100d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
101d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojint main (int argc, char **argv)
102d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
103d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sigset_t	setsig, 		/* Initial signal mask */
104d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			newsetsig;		/* Second signal mask */
105d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	pid_t		pid = getpid ();	/* Process ID (of this process) */
106d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
107d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/* Print out program header */
108d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("%s: IPC TestSuite program\n\n", *argv);
109d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
1104bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	/*
1114bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Establish signal handler for each signal & reset "valid signals"
1124bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * array
113d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
114d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	init_sig ();
115d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	reset_valid_sig ();
116d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
117d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sigemptyset(&setsig);
118d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigprocmask (SIG_SETMASK, &setsig, (sigset_t *) NULL) < 0)
119d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigprocmask failed", __LINE__);
120d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
121d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
122d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Send SIGILL, SIGALRM & SIGIOT signals to this process:
123d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
124d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * First indicate which signals the signal handler should expect
125d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * by setting the corresponding valid_sig[] array fields.
126d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
1272c28215423293e443469a07ae7011135d058b671Garrett Cooper	 * Then send the signals to this process.
128d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
1294bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * And finally verify that the signals were caught by the signal
1304bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * handler by checking to see if the corresponding valid_sig[] array
131d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * fields were reset.
132d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
133d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\tSend SIGILL, SIGALRM, SIGIOT signals to process\n");
134d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	valid_sig [SIGILL] = 1;
135d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	valid_sig [SIGALRM] = 1;
136d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	valid_sig [SIGIOT] = 1;
137d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
138d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGILL);
139d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGALRM);
140d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGIOT);
141d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
142d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (valid_sig [SIGILL])
143d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		error ("failed to receive SIGILL signal!", __LINE__);
144d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (valid_sig [SIGALRM])
145d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		error ("failed to receive SIGALRM signal!", __LINE__);
146d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (valid_sig [SIGIOT])
147d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		error ("failed to receive SIGIOT signal!", __LINE__);
148d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
1494bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	/*
150d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Block SIGILL, SIGALRM & SIGIOT signals:
151d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
1524bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * First initialize the signal set so that all signals are excluded,
153d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * then individually add the signals to block to the signal set.
154d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
155d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Then change the process signal mask with sigprocmask (SIG_SETMASK).
156d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
157d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Verify that the desired signals are blocked from interrupting the
1584bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * process, by sending both blocked and unblocked signals to the
159d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * process.  Only the unblocked signals should interrupt the process.
160d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
161d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\n\tBlock SIGILL, SIGALRM, SIGIOT signals, " \
162d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		"and resend signals + others\n");
163d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sigemptyset(&setsig);
164d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
165d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigaddset (&setsig, SIGIOT) < 0)
166d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigaddset (SIGIOT) failed", __LINE__);
167d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigaddset (&setsig, SIGILL) < 0)
168d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigaddset (SIGILL) failed", __LINE__);
169d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigaddset (&setsig, SIGALRM) < 0)
170d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigaddset (SIGALRM) failed", __LINE__);
171d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
172d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigprocmask (SIG_SETMASK, &setsig, (sigset_t *) NULL) < 0)
173d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigaddset (SIGALRM) failed", __LINE__);
174d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
175d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	valid_sig [SIGFPE] = 1;
176d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	valid_sig [SIGTERM] = 1;
177d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	valid_sig [SIGINT] = 1;
178d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
179d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGILL);
180d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGALRM);
181d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGIOT);
182d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGFPE);
183d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGTERM);
184d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGINT);
185d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
186d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (valid_sig [SIGFPE])
187d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("failed to receive SIGFPE signal!", __LINE__);
188d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (valid_sig [SIGTERM])
189d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("failed to receive SIGTERM signal!", __LINE__);
190d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (valid_sig [SIGINT])
191d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("failed to receive SIGINT signal!", __LINE__);
192d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
1934bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	/*
194d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Block additional SIGFPE, SIGTERM & SIGINT signals:
195d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
196d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Create an other signal set to contain the additional signals to block
197d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * and add the signals to block to the signal set.
198d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
199d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Change the process signal mask to block the additional signals
200d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * with the sigprocmask (SIG_BLOCK) function.
201d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
2024bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Verify that all of the desired signals are now blocked from
2034bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * interrupting the process.  None of the specified signals should
204d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * interrupt the process until the process signal mask is changed.
205d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
206d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\n\tBlock rest of signals\n");
207d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sigemptyset (&newsetsig);
208d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
209d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sigaddset (&newsetsig, SIGFPE);
210d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sigaddset (&newsetsig, SIGTERM);
211d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sigaddset (&newsetsig, SIGINT);
212d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
213d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigprocmask (SIG_BLOCK, &newsetsig, &setsig) < 0)
214d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigprocmask failed", __LINE__);
215d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
216d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGILL);
217d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGALRM);
218d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGIOT);
219d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGFPE);
220d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGTERM);
221d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	kill (pid, SIGINT);
222d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
2234bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	/*
224d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Wait two seconds just to make sure that none of the specified
225d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * signals interrupt the process (They should all be blocked).
226d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
227d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sleep (2);
228d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
229d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/*
230d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Change the process signal mask:
231d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
232d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Now specifiy a new process signal set to allow the SIGINT signal
233d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * to interrupt the process.  Create the signal set by initializing
234d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * the signal set with sigfillset () so that all signals are included
235d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * in the signal set, then remove the SIGINT signal from the set with
236d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * sigdelset ().
237d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
2384bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	 * Force the  process to suspend execution until delivery of an
239d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * unblocked signal (SIGINT in this case) with sigsuspend ().
240d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 *
241d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 * Additionally, verify that the SIGINT signal was received.
242d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	 */
243d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	valid_sig [SIGINT] = 1;
244d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
245d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\n\tChange signal mask & wait until signal interrupts process\n");
246d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigfillset (&setsig) < 0)
247d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigfillset failed", __LINE__);
248d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigdelset (&setsig, SIGINT) < 0)
249d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigdelset failed", __LINE__);
250d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (sigsuspend(&setsig) != -1 || errno != 4)
251d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sys_error ("sigsuspend failed", __LINE__);
252d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
253d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (valid_sig [SIGINT])
254d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		error ("failed to receive SIGIOT signal!", __LINE__);
255d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
256d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/* Program completed successfully -- exit */
257d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	printf ("\nsuccessful!\n");
258d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
259d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	return (0);
260d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
261d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
262d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
263d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                             init_sig ()                              |
264d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
265d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
266d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Initialize the signal vector for ALL possible signals     |
267d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            (as defined in /usr/include/sys/signal.h) except for      |
268d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            the following signals which cannot be caught or ignored:  |
269d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
270d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|              o  SIGKILL (9)                                          |
271d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|              o  SIGSTOP (17)                                         |
272d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|              o  SIGCONT (19)                                         |
273d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
274d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Returns:   n/a                                                       |
275d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
276d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
277d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid init_sig ()
278d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
279d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	struct sigaction invec;
280d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	char 	msg [256];		/* Buffer for error message */
281d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int 	i;
282d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
283d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	for (i=1; i<=SIGMAX; i++) {
284d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
285d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		/* Cannot catch or ignore the following signals */
286d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#ifdef _IA64    /* SIGWAITING not supported, RESERVED */
287d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if ((i == SIGKILL) || (i == SIGSTOP) ||
288d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		    (i == SIGCONT) || (i == SIGWAITING)) continue;
289d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#else
290d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj# ifdef _LINUX_
291d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj       		if ((i == SIGKILL) || (i == SIGSTOP) || ((i>=32)&&(i<=34))) continue;
292d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj# else
293d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (i == SIGKILL || i == SIGSTOP || i == SIGCONT) continue;
294d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj# endif
295d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj#endif
296d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
297d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		invec.sa_handler = (void (*)(int)) handler;
298d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		sigemptyset (&invec.sa_mask);
299d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		invec.sa_flags = 0;
300d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
301d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		if (sigaction (i, &invec, (struct sigaction *) NULL) < 0) {
302d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			sprintf (msg, "sigaction failed on signal %d", i);
303d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj			error (msg, __LINE__);
304d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		}
305d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
306d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
307d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
308d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
309d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                             handler ()                               |
310d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
311d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
312d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Signal catching function.  As specified in init_sig_vec() |
313d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            this function is automatically called each time a signal  |
314d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            is received by the process.                               |
315d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
316d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            Once receiving the signal, verify that the corresponding  |
317d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|            signal was expected.                                      |
318d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
319d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Returns:   Aborts program if an unexpected signal was received.      |
320d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
321d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
322d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid handler (int sig)//, int code, struct sigcontext *scp)
323d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
324d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	char 	msg [256];
325d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
326d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	/* Check to insure that expected signal was received */
327d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	if (valid_sig [sig]) {
328d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		valid_sig [sig] = 0;
329d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		printf ("\treceived signal: (%s)\n", signames[sig]);
330d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	} else {
331f3a83d59cce260ab513313b2c43c41fc16983959robbiew		sprintf (msg, "unexpected signal (%d,%s)", sig, (sig<32)?signames[sig]:"unknown signal");
332d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		error (msg, __LINE__);
333d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	}
334d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
335d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
336d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
337d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                         reset_valid_sig ()                           |
338d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
339d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
340d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Reset the valid "signal" array                            |
341d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
342d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Returns:   n/a                                                       |
343d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
344d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
345d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid reset_valid_sig ()
346d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
347d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	int i;
348d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
349d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	for (i=0; i< (SIGMAX + 1); i++)
350d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj		valid_sig [i] = 0;
351d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
352d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
353d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
354d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                             sys_error ()                             |
355d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
356d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
357d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Creates system error message and calls error ()           |
358d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
359d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
360d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid sys_error (const char *msg, int line)
361d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
362d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	char syserr_msg [256];
363d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
364d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	sprintf (syserr_msg, "%s: %s\n", msg, strerror (errno));
365d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	error (syserr_msg, line);
366d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj}
367d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj
368d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj/*---------------------------------------------------------------------+
369d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                               error ()                               |
370d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| ==================================================================== |
371d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
372d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj| Function:  Prints out message and exits...                           |
373d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj|                                                                      |
374d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj+---------------------------------------------------------------------*/
375d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanojvoid error (const char *msg, int line)
376d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj{
377d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	fprintf (stderr, "ERROR [line: %d] %s\n", line, msg);
378d1c7ea471d417c9319bdf0ce5bb1fed011283b65iyermanoj	exit (-1);
379ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
380