Introduction
Following is a short simple hack implementing an RAII based signal handling guard passing signals as template parameters.
The guard constructor sets a signal handler for a list of signals and the destructor resets the original signal handlers. The code makes use of variadic templates in a way I find pretty cool.
There is not much to this blog entry except for the code showing how to apply a function to each element in a list of template parameters.
Using the code
A small example using standard RAII style shows how the signal guard can be used:
// test program int main(){ { // install a signal handler for some signals sigguard<SIGINT,SIGHUP>([](int sig){}); // code, code, code ... // ... } // old signal handler re-installed when 'sigguard' destructor runs // ... }
The code
#include <stack> #include <iostream> #include <utility> #include <csignal> #include <cstring> template<int...SIGS> class sigguard{ public: // ctor sigguard(sighandler_t fsig):fsig_(fsig){ setsigs(std::integer_sequence<int,SIGS...>()); } // dtor ~sigguard(){ while(!oldhandlers_.empty()){ auto const[sig,fsig]=oldhandlers_.top(); oldhandlers_.pop(); signal(sig,fsig); } } private: // install signal handler for list of signals template<int...sigs> void setsigs(std::integer_sequence<int,sigs...>){ using xxx=int[]; (void)xxx{(setsig(sigs),0)...}; } // set a single signal handler and save the old one so it can be set in the dtor void setsig(int sig){ auto oldhandler=signal(sig,fsig_); if(oldhandler==SIG_ERR){ throw std::runtime_error(std::string("could not set signal handler: ")+strsignal(sig)); } oldhandlers_.push(std::make_pair(sig,oldhandler)); } // old signal handlers std::stack<std::pair<int,sighandler_t>>oldhandlers_; // signal handler function sighandler_t fsig_; };
No comments:
Post a Comment