00001 /*! \file signals.c 00002 This file contains all signals related functions. 00003 */ 00004 00005 #include "signals.h" 00006 00007 /*! \brief Data structure used to put the new signals mask. 00008 */ 00009 00010 static sigset_t new_set; 00011 00012 /*! \brief Signal to manipulate. 00013 */ 00014 00015 static int my_sig = -1; 00016 00017 /*! \brief Set the signal to manipulate. 00018 \param sig Signal to manipulate. 00019 */ 00020 00021 void set_signal (int sig) 00022 { my_sig = sig; } 00023 00024 /*! \example test_signals.c 00025 This file shows how to use the simple signal functions. 00026 */ 00027 00028 /*! \brief Block the signal my_sig only. All other signals are allowed. 00029 \return If the operation was successful, the function returns 0. Otherwise tha function returns 1. Please note that 00030 this function should never fail. If it fails, then you are in deep trouble ... check your system. 00031 \warning You must call set_signal() before you can use this function !. 00032 */ 00033 00034 int block_all_signal() 00035 { 00036 int cr; 00037 00038 if (sigemptyset (&new_set) == -1) { return 1; } 00039 00040 if (sigaddset (&new_set, my_sig) == -1) { return 1; } 00041 00042 /*****************************************************************/ 00043 /* WARNING: This is weird, but sigprocmask() can be interrupted. */ 00044 /* You must test errno. */ 00045 /*****************************************************************/ 00046 00047 cr = sigprocmask(SIG_BLOCK, &new_set, 0); 00048 00049 while ((cr == -1) && (errno == EINTR)) 00050 { cr = sigprocmask(SIG_BLOCK, &new_set, 0); } 00051 if (cr == -1) { return 1; } 00052 00053 return 0; 00054 } 00055 00056 /*! \example test_signals.c 00057 This file shows how to use the simple signal functions. 00058 */ 00059 00060 /*! \brief Unblock the signal my_sig. 00061 \return If the operation was successful, the function returns 0. Otherwise tha function returns 1. Please note that 00062 this function should never fail. If it fails, then you are in deep trouble ... check your system. 00063 \warning You must call set_signal() before you can use this function !. 00064 */ 00065 00066 int retore_signal() 00067 { 00068 int cr; 00069 00070 if (sigemptyset (&new_set) == -1) { return 1; } 00071 00072 if (sigaddset (&new_set, my_sig) == -1) { return 1; } 00073 00074 /*****************************************************************/ 00075 /* WARNING: This is weird, but sigprocmask() can be interrupted. */ 00076 /* You must test errno. */ 00077 /*****************************************************************/ 00078 00079 cr = sigprocmask(SIG_UNBLOCK, &new_set, 0); 00080 00081 while ((cr == -1) && (errno == EINTR)) 00082 { cr = sigprocmask(SIG_UNBLOCK, &new_set, 0); } 00083 if (cr == -1) { return 1; } 00084 00085 return 0; 00086 } 00087 00088 /*! \example test_signals.c 00089 This file shows how to use the simple signal functions. 00090 */ 00091 00092 /*! \brief Look if there are any my_sig pending signals. If it is the case, the pensding signales are activated. 00093 \return If the operation was successful, the function returns 0. Otherwise tha function returns 1. Please note that 00094 this function should never fail. If it fails, then you are in deep trouble ... check your system. 00095 \warning If you look at the man page for the function 'sigsuspend()', you see that 'sigsuspend()' can set 'errno' to 00096 EINTR. But you must ignore it, otherwise you create an infinite loop. Indeed, every time 'sigsuspend()' raises a 00097 pending signal, 'sigsuspend()' is interrupted ... And therefore, EINTR is set!. 00098 You must call set_signal() before you can use this function !. 00099 */ 00100 00101 int get_pending_signals() 00102 { 00103 sigset_t pendsig; 00104 sigset_t sigint_set; 00105 00106 if (sigfillset(&sigint_set) == -1) { return 1; } 00107 00108 if (sigdelset(&sigint_set, my_sig) == -1) { return 1; } 00109 00110 if (sigpending(&pendsig) == -1) { return 1; } 00111 00112 if (sigismember (&pendsig, my_sig) == 1) 00113 { sigsuspend (&sigint_set); } 00114 00115 return 0; 00116 } 00117 00118 /*! \example test_signals.c 00119 This file shows how to use the simple signal functions. 00120 */ 00121 00122 /*! \brief Set a signal handler on the signal my_sig. 00123 \param handler Pointer to the signal's handler. The function's prototype should look something like: 00124 void function_name(int). 00125 \return If the operation was successful, the function returns 0. Otherwise tha function returns 1. Please note that 00126 this function should never fail. If it fails, then you are in deep trouble ... check your system. 00127 \warning You must call set_signal() before you can use this function !. 00128 */ 00129 00130 int set_signal_handler(void (*handler)(int)) 00131 { 00132 struct sigaction new_sig_settings; 00133 00134 new_sig_settings.sa_handler = handler; 00135 00136 /******************************************************************/ 00137 /* 'sa_mask' represents the set of signals that should be blocked */ 00138 /* while the current signal is being processed. By default the */ 00139 /* current signal is blocked too (unless SA_NODEFER or SA_NOMASK */ 00140 /* is set in 'sa_flags'). */ 00141 /* */ 00142 /* Here we say that *only* signals my_sig will be blocked while */ 00143 /* the current signal is being processed. And, of course, the */ 00144 /* current signal is blocked too while it is executed. This is */ 00145 /* the default behaviour and I think it is safe. */ 00146 /******************************************************************/ 00147 00148 if (sigemptyset (&(new_sig_settings.sa_mask)) == -1) { return 1; } 00149 00150 if (sigaddset (&(new_sig_settings.sa_mask), my_sig) == -1) { return 1; } 00151 00152 /******************************************************************/ 00153 /* No special mask needed. */ 00154 /******************************************************************/ 00155 00156 new_sig_settings.sa_flags = 0; 00157 00158 /******************************************************************/ 00159 /* We want to catch my_sig. */ 00160 /* I mean only this signal will be linked to an handler. */ 00161 /******************************************************************/ 00162 00163 if (sigaction(my_sig, &new_sig_settings, 0) == -1) { return 1; } 00164 00165 /******************************************************************/ 00166 /* OK, now this is the situation: */ 00167 /* */ 00168 /* - We accept *ALL* signals. */ 00169 /* - When a signal is processed, all other signals are blocked, */ 00170 /* including the current signal itself. */ 00171 /* - We set a handler to my_sig only. */ 00172 /******************************************************************/ 00173 00174 return 0; 00175 } 00176 00177 /*! \example test_signals.c 00178 This file shows how to use the simple signal functions. 00179 */ 00180 00181 00182