Home | History | Annotate | Download | only in disktest
      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 (at) 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
     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 
    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 
    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