• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Disktest
3 * Copyright (c) International Business Machines Corp., 2005
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 the
13 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 *  Please send e-mail to yardleyb@us.ibm.com if you have
20 *  questions or comments.
21 *
22 *  Project Website:  TBD
23 *
24 * $Id: signals.c,v 1.1 2008/02/14 08:22:23 subrata_modak Exp $
25 */
26 #ifdef WINDOWS
27 #include <windows.h>
28 #else
29 #include <pthread.h>
30 #endif
31 #include <signal.h>
32 #include "threading.h"
33 #include "signals.h"
34 
35 /*
36  * global variable used to indicate what signal
37  * (if any) has been caught
38  */
39 int handled_signal = -1;
40 int signal_action = SIGNAL_NONE;
41 
42 /*
43  * mutex to be used whenever accessing the above
44  * global data
45  */
46 #ifdef WINDOWS
47 HANDLE sig_mutex;
48 #else
49 pthread_mutex_t sig_mutex = PTHREAD_MUTEX_INITIALIZER;
50 #endif
51 
52 #ifdef WINDOWS
sig_handler(int sig)53 void sig_handler(int sig)
54 #else
55 void *sig_handler(void *arg)
56 #endif
57 {
58 #ifndef WINDOWS
59 	sigset_t signal_set;
60 	int sig;
61 	int rv;
62 
63 	/* wait for any and all signals */
64 	sigfillset(&signal_set);
65 #ifdef AIX
66 	/* except in AIX, can't sigwait on this signals */
67 	sigdelset(&signal_set, SIGKILL);
68 	sigdelset(&signal_set, SIGWAITING);
69 	sigdelset(&signal_set, SIGSTOP);
70 #endif
71 
72 	for (;;) {
73 		rv = sigwait(&signal_set, &sig);
74 #endif
75 
76 		switch (sig) {
77 		case SIGQUIT:
78 			LOCK(sig_mutex);
79 			handled_signal = SIGQUIT;
80 			signal_action |= SIGNAL_STOP;
81 			UNLOCK(sig_mutex);
82 			break;
83 
84 		case SIGINT:
85 			LOCK(sig_mutex);
86 			handled_signal = SIGINT;
87 			signal_action |= SIGNAL_STOP;
88 			UNLOCK(sig_mutex);
89 			break;
90 
91 		case SIGTERM:
92 			LOCK(sig_mutex);
93 			handled_signal = SIGTERM;
94 			signal_action |= SIGNAL_STOP;
95 			UNLOCK(sig_mutex);
96 			break;
97 
98 		case SIGHUP:
99 			LOCK(sig_mutex);
100 			handled_signal = SIGHUP;
101 			signal_action |= SIGNAL_STOP;
102 			UNLOCK(sig_mutex);
103 			break;
104 
105 		case SIGUSR1:
106 			LOCK(sig_mutex);
107 			handled_signal = SIGUSR1;
108 			signal_action |= SIGNAL_STAT;
109 			UNLOCK(sig_mutex);
110 			break;
111 
112 			/* whatever you need to do for other signals */
113 		default:
114 			LOCK(sig_mutex);
115 			handled_signal = 0;
116 			UNLOCK(sig_mutex);
117 			break;
118 		}
119 #ifndef WINDOWS
120 	}
121 	return NULL;
122 #endif
123 }
124 
setup_sig_mask(void)125 void setup_sig_mask(void)
126 {
127 #ifndef WINDOWS
128 	sigset_t signal_set;
129 	pthread_t sig_thread;
130 #endif
131 
132 #ifdef WINDOWS
133 	if ((sig_mutex = CreateMutex(NULL, FALSE, NULL)) == NULL) {
134 		return;
135 	}
136 #endif
137 
138 	/* block all signals */
139 #ifdef WINDOWS
140 	signal(SIGINT, sig_handler);
141 	signal(SIGTERM, sig_handler);
142 	signal(SIGUSR1, sig_handler);
143 #else
144 	sigemptyset(&signal_set);
145 	sigaddset(&signal_set, SIGINT);
146 	sigaddset(&signal_set, SIGHUP);
147 	sigaddset(&signal_set, SIGQUIT);
148 	sigaddset(&signal_set, SIGTERM);
149 	sigaddset(&signal_set, SIGUSR1);
150 
151 #ifdef AIX
152 	sigthreadmask(SIG_SETMASK, &signal_set, NULL);
153 #else
154 	pthread_sigmask(SIG_SETMASK, &signal_set, NULL);
155 #endif
156 
157 	/* create the signal handling thread */
158 	pthread_create(&sig_thread, NULL, sig_handler, NULL);
159 #endif
160 }
161 
clear_stat_signal(void)162 void clear_stat_signal(void)
163 {
164 	if (signal_action & SIGNAL_STAT) {
165 		LOCK(sig_mutex);
166 		signal_action &= ~SIGNAL_STAT;
167 		UNLOCK(sig_mutex);
168 	}
169 }
170