Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Examples  

signals.c

Go to the documentation of this file.
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 

Generated on Thu Apr 3 16:23:44 2003 for Common_C_libraries by doxygen1.3-rc1