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