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