Signal.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "lib/config.h"
00012
00013 #ifndef WIN32
00014
00015 #include <stdlib.h>
00016 #include <signal.h>
00017 #include <string.h>
00018
00019 #include "lib/io.h"
00020 #include "lib/Signal.h"
00021
00022 int CSignal::signals[NUMTRAPPEDSIGS]={SIGINT, SIGURG};
00023 struct sigaction CSignal::oldsigaction[NUMTRAPPEDSIGS];
00024 bool CSignal::active=false;
00025 bool CSignal::cancel_computation=false;
00026 bool CSignal::cancel_immediately=false;
00027
00028 CSignal::CSignal()
00029 : CSGObject()
00030 {
00031 }
00032
00033 CSignal::~CSignal()
00034 {
00035 if (!unset_handler())
00036 SG_PRINT("error uninitalizing signal handler\n");
00037 }
00038
00039 void CSignal::handler(int signal)
00040 {
00041 if (signal == SIGINT)
00042 {
00043 SG_SPRINT("\nImmediately return to prompt / Prematurely finish computations / Do nothing (I/P/D)? ");
00044 char answer=fgetc(stdin);
00045
00046 if (answer == 'I')
00047 {
00048 unset_handler();
00049 set_cancel(true);
00050 if (sg_print_error)
00051 sg_print_error(stdout, "sg stopped by SIGINT\n");
00052 }
00053 else if (answer == 'P')
00054 set_cancel();
00055 else
00056 SG_SPRINT("Continuing...\n");
00057 }
00058 else if (signal == SIGURG)
00059 set_cancel();
00060 else
00061 SG_SPRINT("unknown signal %d received\n", signal);
00062 }
00063
00064 bool CSignal::set_handler()
00065 {
00066 if (!active)
00067 {
00068 struct sigaction act;
00069 sigset_t st;
00070
00071 sigemptyset(&st);
00072 for (int32_t i=0; i<NUMTRAPPEDSIGS; i++)
00073 sigaddset(&st, signals[i]);
00074
00075 #ifndef __INTERIX
00076 act.sa_sigaction=NULL;
00077 #endif
00078 act.sa_handler=CSignal::handler;
00079 act.sa_mask = st;
00080 act.sa_flags = 0;
00081
00082 for (int32_t i=0; i<NUMTRAPPEDSIGS; i++)
00083 {
00084 if (sigaction(signals[i], &act, &oldsigaction[i]))
00085 {
00086 SG_SPRINT("Error trapping signals!\n");
00087 for (int32_t j=i-1; j>=0; j--)
00088 sigaction(signals[i], &oldsigaction[i], NULL);
00089
00090 clear();
00091 return false;
00092 }
00093 }
00094
00095 active=true;
00096 return true;
00097 }
00098 else
00099 return false;
00100 }
00101
00102 bool CSignal::unset_handler()
00103 {
00104 if (active)
00105 {
00106 bool result=true;
00107
00108 for (int32_t i=0; i<NUMTRAPPEDSIGS; i++)
00109 {
00110 if (sigaction(signals[i], &oldsigaction[i], NULL))
00111 {
00112 SG_SPRINT("error uninitalizing signal handler for signal %d\n", signals[i]);
00113 result=false;
00114 }
00115 }
00116
00117 if (result)
00118 clear();
00119
00120 return result;
00121 }
00122 else
00123 return false;
00124 }
00125
00126 void CSignal::clear_cancel()
00127 {
00128 cancel_computation=false;
00129 cancel_immediately=false;
00130 }
00131
00132 void CSignal::set_cancel(bool immediately)
00133 {
00134 cancel_computation=true;
00135
00136 if (immediately)
00137 cancel_immediately=true;
00138 }
00139
00140 void CSignal::clear()
00141 {
00142 clear_cancel();
00143 active=false;
00144 memset(&CSignal::oldsigaction, 0, sizeof(CSignal::oldsigaction));
00145 }
00146 #endif //WIN32