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 NULL; 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} 170