signals.c revision 2c28215423293e443469a07ae7011135d058b671
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 */
39int handled_signal = -1;
40int signal_action = SIGNAL_NONE;
41
42/*
43 * mutex to be used whenever accessing the above
44 * global data
45 */
46#ifdef WINDOWS
47HANDLE sig_mutex;
48#else
49pthread_mutex_t sig_mutex = PTHREAD_MUTEX_INITIALIZER;
50#endif
51
52#ifdef WINDOWS
53void sig_handler( int sig )
54#else
55void* 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 (void *)0;
122#endif
123}
124
125void 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
162void 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}