Imported submodules from libi2ncommon which are now licensed under GPL version 2...
authorThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 6 Apr 2009 14:20:40 +0000 (16:20 +0200)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 6 Apr 2009 14:20:40 +0000 (16:20 +0200)
i2ncommon/containerfunc.cpp [new file with mode: 0644]
i2ncommon/containerfunc.hpp [new file with mode: 0644]
i2ncommon/signalfunc.cpp [new file with mode: 0644]
i2ncommon/signalfunc.hpp [new file with mode: 0644]

diff --git a/i2ncommon/containerfunc.cpp b/i2ncommon/containerfunc.cpp
new file mode 100644 (file)
index 0000000..80e3bce
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+The software in this package is distributed under the GNU General
+Public License version 2 (with a special exception described below).
+
+A copy of GNU General Public License (GPL) is included in this distribution,
+in the file COPYING.GPL.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file
+does not by itself cause the resulting work to be covered
+by the GNU General Public License.
+
+However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+/** @file
+ *
+ * (c) Copyright 2007-2008 by Intra2net AG
+ * 
+ * opensource@intra2net.com
+ */
+
+#include "containerfunc.hpp"
diff --git a/i2ncommon/containerfunc.hpp b/i2ncommon/containerfunc.hpp
new file mode 100644 (file)
index 0000000..2e61e54
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+The software in this package is distributed under the GNU General
+Public License version 2 (with a special exception described below).
+
+A copy of GNU General Public License (GPL) is included in this distribution,
+in the file COPYING.GPL.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file
+does not by itself cause the resulting work to be covered
+by the GNU General Public License.
+
+However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+/** @file
+ * @brief some helper for handling (STL) data structures.
+ *
+ * @author Reinhard Pfau \<Reinhard.Pfau@intra2net.com\>
+ *
+ * (c) Copyright 2007-2008 by Intra2net AG
+ * 
+ * opensource@intra2net.com
+ */
+
+#ifndef _I2N_CONTAINERFUNC_HPP_
+#define _I2N_CONTAINERFUNC_HPP_
+
+#include <map>
+#include <list>
+#include <set>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+
+namespace I2n {
+
+
+/**
+ * convenience class to insert key-value pairs into a map.
+ */
+template<typename K, typename V>
+class MapFiller
+{
+        std::map<K,V> & MapRef;
+
+    public:
+        MapFiller( std::map<K,V> & map_ref)
+        : MapRef(map_ref)
+        {
+        }
+
+        MapFiller& operator () (const K& key, const V& value)
+        {
+            MapRef[key]= value;
+            return *this;
+        }
+
+}; // eo class MapFiller
+
+
+/**
+ * convenience class to fill values into a container (using push_back).
+ */
+template<
+    typename T,
+    template< typename, typename> class C= std::list,
+    typename Alloc = std::allocator< T >
+>
+class PushBackFiller
+{
+        C< T, Alloc > &CRef;
+    public:
+        PushBackFiller( C<T, Alloc > & c )
+        : CRef(c)
+        {}
+
+        PushBackFiller& operator () (const T& value)
+        {
+            CRef.push_back(value);
+            return *this;
+        } // eo operator ()
+
+}; // eo class PushBackFiller
+
+
+template<
+    typename T,
+    template< typename, typename > class C,
+    typename Alloc
+>
+PushBackFiller< T, C, Alloc > get_push_back_filler( C< T, Alloc >& c)
+{
+    return PushBackFiller< T, C, Alloc >(c);
+} // eo get_push_back_filler(C< T, Alloc >&)
+
+
+/**
+ * convenience class for transient construction of a container including values.
+ */
+template<
+    typename T,
+    template< typename, typename> class C= std::list,
+    typename Alloc = std::allocator< T >
+>
+class TransientPushBackFiller
+{
+        C< T, Alloc > MyC;
+    public:
+        typedef C< T, Alloc > CType;
+    
+        TransientPushBackFiller()
+        {}
+        
+        TransientPushBackFiller& operator () (const T& value)
+        {
+            MyC.push_back(value);
+            return *this;
+        } // eo operator ()
+        
+        operator CType () const { return MyC; }
+}; // eo class TransientPushBackFiller
+
+
+/**
+ * convenience class for transient construction of a map including values.
+ */
+template<typename K, typename V>
+class TransientMapFiller
+{
+        std::map<K,V> Map;
+    
+    public:
+        typedef std::map< K, V > CType;
+    
+    
+        TransientMapFiller( )
+        {
+        }
+        
+        TransientMapFiller& operator () (const K& key, const V& value)
+        {
+            Map[key]= value;
+            return *this;
+        }
+        
+        operator CType () const { return Map; }
+}; // eo class MapFiller
+
+
+
+
+/**
+ * returns the keys of a map as a list.
+ * @param the_map the map.
+ * @param the_keys the list where the keys are added to.
+ * @return @a true.
+ */
+template< typename K, typename V >
+bool get_key_list( const std::map< K, V >& the_map, std::list< K >& the_keys )
+{
+    for(typename std::map< K, V >::const_iterator it= the_map.begin();
+        it != the_map.end();
+        ++it )
+    {
+        the_keys.push_back( it->first );
+    }
+    return true;
+}  // eo get_key_list(const std::map< K,V >, std::list< K >&)
+
+
+/**
+ * returns the keys of a map as a list.
+ * @param the_map the map.
+ * @return the list of keys.
+ */
+template< typename K, typename V >
+std::list< K > get_key_list( const std::map< K, V>& the_map)
+{
+    std::list< K > result;
+    get_key_list(the_map, result);
+    return result;
+} // eo get_key_list(const std::map< K,V >)
+
+
+/**
+ * returns the keys of a map as a set.
+ * @param the_map the map.
+ * @param the_keys the set where the keys are added to.
+ * @return @a true.
+ */
+template< typename K, typename V >
+bool get_key_set( const std::map< K, V >& the_map, std::set< K >& the_keys )
+{
+    for(typename std::map< K, V >::const_iterator it= the_map.begin();
+        it != the_map.end();
+        ++it )
+    {
+        the_keys.insert( it->first );
+    }
+    return true;
+}  // eo get_key_set(const std::map< K,V >, std::set< K >&)
+
+
+/**
+ * returns the keys of a map as a set.
+ * @param the_map the map.
+ * @return the set of keys.
+ */
+template< typename K, typename V >
+std::list< K > get_key_set( const std::map< K, V>& the_map)
+{
+    std::set< K > result;
+    get_key_set(the_map, result);
+    return result;
+} // eo get_key_set(const std::map< K,V >)
+
+
+/**
+ * functor version of new().
+ * can be used for deferred instantiation of objects.
+ */
+template<
+    typename T
+>
+struct New
+{
+    typedef T* result_type;
+    
+    result_type operator() () 
+    {
+        return new T;
+    }
+    
+    template<typename Arg1>
+    result_type operator() (Arg1 arg1)
+    {
+        return new T(arg1);
+    }
+    
+    template<typename Arg1, typename Arg2>
+    result_type operator() (Arg1 arg1,Arg2 arg2)
+    {
+        return new T(arg1,arg2);
+    }
+    
+    template<typename Arg1, typename Arg2, typename Arg3>
+    result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3)
+    {
+        return new T(arg1,arg2,arg3);
+    }
+    
+    template<typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+    result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4)
+    {
+        return new T(arg1,arg2,arg3,arg4);
+    }
+    
+    template<typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+    result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5)
+    {
+        return new T(arg1,arg2,arg3,arg4,arg5);
+    }
+    
+}; // eo struct New
+
+
+
+
+/**
+ * functor version of boost::shared_ptr = new().
+ * can be used for deferred instantiation of objects.
+ */
+template<
+    typename T
+>
+struct SharedPtrNew
+{
+    typedef boost::shared_ptr<T> result_type;
+    
+    result_type operator() () 
+    {
+        return result_type(new T);
+    }
+    
+    template<typename Arg1>
+    result_type operator() (Arg1 arg1)
+    {
+        return result_type(new T(arg1));
+    }
+    
+    template<typename Arg1, typename Arg2>
+    result_type operator() (Arg1 arg1,Arg2 arg2)
+    {
+        return result_type(new T(arg1,arg2));
+    }
+    
+    template<typename Arg1, typename Arg2, typename Arg3>
+    result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3)
+    {
+        return result_type(new T(arg1,arg2,arg3));
+    }
+    
+    template<typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+    result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4)
+    {
+        return result_type(new T(arg1,arg2,arg3,arg4));
+    }
+    
+    template<typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+    result_type operator() (Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5)
+    {
+        return result_type(new T(arg1,arg2,arg3,arg4,arg5));
+    }
+    
+}; // eo struct SharedPtrNew
+
+
+
+/*
+** classes holding a shared or weak pointer.
+** designed to be used as policy classes...
+** (but may be used for other purposes, too)
+*/
+
+template<
+    class X
+>
+class SharedOwnership
+{
+    public:
+    
+        SharedOwnership( boost::shared_ptr< X > ptr)
+        : StoredPtr(ptr)
+        {}
+        
+        
+        boost::shared_ptr< X > get_ptr() const { return StoredPtr; }
+    
+    public:
+    
+        boost::shared_ptr< X > StoredPtr;
+}; // eo class SharedOwnership
+
+
+
+template<
+    class X
+>
+class WeakOwnership
+{
+    public:
+    
+        WeakOwnership( boost::shared_ptr< X > ptr)
+        : StoredPtr(ptr)
+        {}
+        
+        
+        boost::shared_ptr< X > get_ptr() const { return StoredPtr.lock(); }
+    
+    public:
+    
+        boost::weak_ptr< X > StoredPtr;
+}; // eo class WeakOwnership
+
+
+
+/*
+** NoOperation
+** ===========
+*/
+
+
+/**
+ * @brief the ultimate class for doing nothing :-)
+ *
+ * Even it sounds odd to have a functor class which is doing nothing it makes
+ * sense to use this class in some situations.
+ *
+ * One example is the usage as Deleter for shared pointers which "own" a pointer to
+ * a static object (i.e. it is not allowed to be really deleted...). Using this class
+ * as Deleter in these pointers enables us to use interfaces which expect a shared pointer
+ * even if we want(/must) to pass pointers to static objects.
+ */
+struct NoOperation
+{
+    NoOperation() {};
+
+    template<
+        typename Arg1
+    >
+    NoOperation(Arg1) {}
+
+    template<
+        typename Arg1, typename Arg2
+    >
+    NoOperation(Arg1, Arg2) {}
+
+    template<
+        typename Arg1, typename Arg2, typename Arg3
+    >
+    NoOperation(Arg1, Arg2, Arg3) {}
+
+    void operator() () const {}
+
+    template<
+        typename Arg1
+    >
+    void operator() (Arg1) const {}
+
+    template<
+        typename Arg1, typename Arg2
+    >
+    void operator() (Arg1, Arg2) const {}
+
+    template<
+        typename Arg1, typename Arg2, typename Arg3
+    >
+    void operator() (Arg1, Arg2, Arg3) const {}
+
+}; // eo struct NoOperation
+
+
+
+} // eo namespace I2n
+
+#endif
diff --git a/i2ncommon/signalfunc.cpp b/i2ncommon/signalfunc.cpp
new file mode 100644 (file)
index 0000000..8cad55e
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+The software in this package is distributed under the GNU General
+Public License version 2 (with a special exception described below).
+
+A copy of GNU General Public License (GPL) is included in this distribution,
+in the file COPYING.GPL.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file
+does not by itself cause the resulting work to be covered
+by the GNU General Public License.
+
+However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+/** @file
+ * @brief implementation of wrapper and tools for signal related stuff.
+ *
+ * @copyright &copy; Copyright 2007-2008 by Intra2net AG
+ *
+ * opensource@intra2net.com
+ */
+
+#include "signalfunc.hpp"
+
+#include <algorithm>
+
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <containerfunc.hpp>
+
+
+namespace I2n
+{
+namespace SystemTools
+{
+
+
+namespace
+{
+
+/**
+ * helper for using sigaddset() as unary function within (STL) algorithms.
+ */
+struct SigAddSet
+{
+    sigset_t *m_set;
+    SigAddSet(sigset_t *set) : m_set(set) {}
+    int operator() (int sig) { return sigaddset(m_set,sig); }
+}; // eo struct SigAddSet
+
+
+
+/**
+ * blocks the given signals while existing.
+ *
+ * This class is the real (internal) implementation of the @a SignalBlocker .
+ *
+ * @internal This internal implementation is used to avoid including signal.h within the header file.
+ * This way, we can keep the header clean; and hide all the internals in the implementation.
+ */
+class _ScopedSignalBlocker : public SystemTools::Detail::SObject
+{
+    public:
+        _ScopedSignalBlocker(const std::vector<SystemTools::Signal>& sigs);
+        ~_ScopedSignalBlocker();
+
+        bool successful() const {return m_set; }
+
+    protected:
+        sigset_t m_sigset[1];
+        sigset_t m_oldsigset[1];
+        bool m_set;
+}; // eo _ScopedSignalBlocker
+
+
+/**
+ * Blocks the given signals.
+ *
+ * Constructs a sigset from the passed signals; and calls sigprocmask to block them.
+ * In case of interruption with EINTR during the call, the call is repeated some times
+ * to get the desired signals blocked.
+ *
+ * @param sigs the vector with the siganls which should be blocked.
+ */
+_ScopedSignalBlocker::_ScopedSignalBlocker(const std::vector<SystemTools::Signal>& sigs)
+{
+    sigemptyset(m_sigset);
+
+    // fill in signals
+    std::for_each(sigs.begin(), sigs.end(), SigAddSet(m_sigset) );
+
+    int res;
+    for(int cnt=1000; cnt-->0;)
+    {
+        res= sigprocmask(SIG_BLOCK,m_sigset, m_oldsigset);
+        if (!res || errno!=EINTR) break;
+    }
+    m_set= (res==0);
+} // eo _ScopedSignalBlocker::_ScopedSignalBlocker()
+
+
+/**
+ * Unblocks the signals by restoring the original block mask.
+ */
+_ScopedSignalBlocker::~_ScopedSignalBlocker()
+{
+    int res;
+    if (!m_set) return;
+    for(int cnt=1000; cnt-->0;)
+    {
+        res= sigprocmask(SIG_SETMASK, m_oldsigset, NULL);
+        if (!res || errno!=EINTR) break;
+    }
+} // eo _ScopedSignalBlocker::~_ScopedSignalBlocker()
+
+
+
+} // eo namespace <anonymous>
+
+
+/*************************************************************************\
+\*************************************************************************/
+
+
+
+/*
+ * Signal
+ */
+/// @cond
+
+const int Signal::VOID= 0;
+
+// helper macro to import the signal nums:
+#define IMPORT(sig) const int Signal::sig = SIG ## sig
+
+IMPORT(HUP);
+IMPORT(INT);
+IMPORT(QUIT);
+IMPORT(ILL);
+IMPORT(TRAP);
+IMPORT(ABRT);
+IMPORT(IOT);
+IMPORT(BUS);
+IMPORT(FPE);
+IMPORT(KILL);
+IMPORT(USR1);
+IMPORT(SEGV);
+IMPORT(USR2);
+IMPORT(PIPE);
+IMPORT(ALRM);
+IMPORT(TERM);
+IMPORT(STKFLT);
+IMPORT(CLD);
+IMPORT(CHLD);
+IMPORT(CONT);
+IMPORT(STOP);
+IMPORT(TSTP);
+IMPORT(TTIN);
+IMPORT(TTOU);
+IMPORT(URG);
+IMPORT(XCPU);
+IMPORT(XFSZ);
+IMPORT(VTALRM);
+IMPORT(PROF);
+IMPORT(WINCH);
+IMPORT(POLL);
+IMPORT(IO);
+IMPORT(PWR);
+IMPORT(SYS);
+
+// remove helper macro
+#undef IMPORT
+
+/// @endcond
+
+int Signal::RT(int num)
+{
+    return SIGRTMIN + num;
+} // eo Signal::RT
+
+
+/*
+ * SignalCode
+ */
+
+
+/// @cond
+
+// basically: define apropriate CODE macro and copy the CODE() parts from hpp:
+
+#undef CODE
+#define CODE(name) const int SignalCode::name = SI_ ## name
+    CODE(USER);    CODE(QUEUE); CODE(TIMER); CODE(MESGQ);
+    CODE(ASYNCIO);
+#undef SIGIO
+    CODE(SIGIO);
+#undef CODE
+#define CODE(name) const int SignalCode::ILL::name = ILL_ ## name
+        CODE(ILLOPC); CODE(ILLOPN); CODE(ILLADR); CODE(ILLTRP);
+        CODE(PRVOPC); CODE(PRVREG); CODE(COPROC); CODE(BADSTK);
+#undef CODE
+#define CODE(name) const int SignalCode::FPE::name = FPE_ ## name
+        CODE(INTDIV); CODE(INTOVF); CODE(FLTDIV); CODE(FLTOVF);
+        CODE(FLTUND); CODE(FLTRES); CODE(FLTINV); CODE(FLTSUB);
+#undef CODE
+#define CODE(name) const int SignalCode::SEGV::name = SEGV_ ## name
+        CODE(MAPERR); CODE(ACCERR);
+#undef CODE
+#define CODE(name) const int SignalCode::BUS::name = BUS_ ## name
+        CODE(ADRALN); CODE(ADRERR); CODE(OBJERR);
+#undef CODE
+#define CODE(name) const int SignalCode::TRAP::name = TRAP_ ## name
+        CODE(BRKPT); CODE(TRACE);
+#undef CODE
+#define CODE(name) const int SignalCode::CHLD::name = CLD_ ## name
+        CODE(EXITED); CODE(KILLED); CODE(DUMPED); CODE(TRAPPED);
+        CODE(STOPPED); CODE(CONTINUED);
+#undef CODE
+#define CODE(name) const int SignalCode::POLL::name = POLL_ ## name
+        CODE(IN); CODE(OUT); CODE(MSG); CODE(ERR); CODE(PRI); CODE(HUP);
+#undef CODE
+/// @endcond
+
+/*
+ * ScopedSignalBlocker
+ */
+
+
+/**
+ * Blocks the given signal.
+ * @param sig the signal which should be blocked.
+ */
+ScopedSignalBlocker::ScopedSignalBlocker(Signal sig)
+{
+    Implementation = new _ScopedSignalBlocker( TransientPushBackFiller< Signal, std::vector >()(sig) );
+} // eo ScopedSignalBlocker::ScopedSignalBlocker
+
+
+ScopedSignalBlocker::ScopedSignalBlocker(Signal sig1, Signal sig2)
+{
+    Implementation = new _ScopedSignalBlocker( TransientPushBackFiller< Signal, std::vector >()(sig1)(sig2) );
+} // eo ScopedSignalBlocker::ScopedSignalBlocker
+
+
+ScopedSignalBlocker::ScopedSignalBlocker(Signal sig1, Signal sig2, Signal sig3)
+{
+    Implementation = new _ScopedSignalBlocker( TransientPushBackFiller< Signal, std::vector >()(sig1)(sig2)(sig3) );
+} // eo ScopedSignalBlocker::ScopedSignalBlocker
+
+
+/**
+ * Blocks the given signals.
+ * @param sigs vector with the signals which should be blocked.
+ */
+ScopedSignalBlocker::ScopedSignalBlocker(const std::vector<Signal>& sigs)
+{
+    Implementation = new _ScopedSignalBlocker( sigs );
+} // eo ScopedSignalBlocker::ScopedSignalBlocker
+
+
+/**
+ * Unblocks the signals by restoring the previous blocking list.
+ */
+ScopedSignalBlocker::~ScopedSignalBlocker()
+{
+    if (Implementation)
+    {
+        delete Implementation;
+        Implementation= NULL;
+    }
+} // eo ScopedSignalBlocker::ScopedSignalBlocker
+
+
+
+/*
+** signal handling
+*/
+
+typedef std::map< int, struct sigaction > SignalActionMap;
+
+namespace {
+
+SignalActionMap original_signal_action;
+
+} // eo namespace <anonymous>
+
+
+/**
+ * @brief installs a new signal action.
+ * @param sig the signal 
+ * @param new_action the new signal action.
+ * @return @a true iff the new signal action was succesfully installed.
+ *
+ * Remembers the original value of the signal handler for later restoring.
+ */
+bool install_signal_handler(
+    Signal sig,
+    struct sigaction& new_action
+)
+{
+    struct sigaction old_action[1];
+    int signum= sig;
+    int res= ::sigaction(signum, &new_action, old_action);
+    if (0 == res)
+    {
+        SignalActionMap::iterator it= original_signal_action.find(signum);
+        if (it == original_signal_action.end())
+        {
+            original_signal_action[signum] = *old_action;
+        }
+    }
+    else if (res > 0)
+    {
+        // some glibc's seem to return the errno instead of storing
+        // it in the appropriate var... *sigh*
+        errno = res;
+    }
+    return (0 == res);
+} // eo install_signal_handler(int,sigaction&)
+
+
+/**
+ * @brief installs a simple signal handler.
+ * @param sig the signal.
+ * @param handler pointer to the signal handler.
+ * @return @a true iff the handler was successfully installed.
+ *
+ * Remembers the original value of the signal handler for later restoring.
+ */
+bool install_signal_handler(
+    Signal sig,
+    void(*handler)(int)
+)
+{
+    struct sigaction new_action;
+    new_action.sa_handler= handler;
+    sigemptyset( &new_action.sa_mask );
+    new_action.sa_flags= 0;
+    new_action.sa_restorer= NULL;
+    return install_signal_handler(sig, new_action);
+} // eo install_signal_handler(signum,void(*)(int))
+
+
+
+/**
+ * @brief installs a signal action handler.
+ * @param sig the signal
+ * @param handler pointer to the signal action handler.
+ * @return @a true iff the action handler was successfully installed.
+ *
+ * Remembers the original value of the signal handler for later restoring.
+ */
+bool install_signal_handler(
+    Signal sig,
+    void(*handler)(int,struct siginfo*,void*)
+)
+{
+    struct sigaction new_action;
+    new_action.sa_sigaction= handler;
+    sigemptyset( &new_action.sa_mask );
+    new_action.sa_flags= SA_SIGINFO;
+    new_action.sa_restorer= NULL;
+    return install_signal_handler(sig, new_action);
+} // eo install_signal_handler(signum,void(*)(int,siginfo_t*,void*))
+
+
+/**
+ * @brief ignores a signal.
+ * @param sig the signal
+ * @return @a true iff the ignore handler was successfully installed.
+ *
+ * Remembers the original value of the signal handler for later restoring.
+ */
+bool ignore_signal(Signal sig)
+{
+    return install_signal_handler(sig, SIG_IGN );
+} // eo ignore_signal(Signal)
+
+
+/**
+ * @brief enables the default signal handler.
+ * @param sig the signal
+ * @return @a true iff the default handler was successfully installed.
+ *
+ * Remembers the original value of the signal handler for later restoring.
+ */
+bool install_default_signal_handler(Signal sig)
+{
+    return install_signal_handler(sig, SIG_DFL );
+} // eo install_default_signal_handler(Signal)
+
+
+/**
+ * @brief restores a signal handle to its original value.
+ * @param sig the signal.
+ * @return @a true iff the handler was sucessfully restored.
+ */
+bool restore_signal_handler(Signal sig)
+{
+    int signum= sig;
+    SignalActionMap::iterator it= original_signal_action.find(signum);
+    int res= -1;
+    if (it != original_signal_action.end())
+    {
+        res= ::sigaction(signum, &(it->second), NULL);
+        if (0 == res)
+        {
+            original_signal_action.erase(it);
+        }
+    }
+    return (0 == res);
+} // eo restore_signal_handler
+
+
+
+/**
+ * @brief convenience function; send's a signal to a process.
+ * @param pid PID of the process which should recive the signal.
+ * @param signal the signal to send.
+ * @return @a true iff sending of the signal succeeded.
+ */
+bool send_signal( pid_t pid, Signal signal)
+{
+    return ::kill(pid, signal.Value) == 0;
+} // eo send_signal(pid_t,Signal)
+
+
+
+} // eo namespace SystemTools
+} // eo namespace I2n
diff --git a/i2ncommon/signalfunc.hpp b/i2ncommon/signalfunc.hpp
new file mode 100644 (file)
index 0000000..00ebd2c
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+The software in this package is distributed under the GNU General
+Public License version 2 (with a special exception described below).
+
+A copy of GNU General Public License (GPL) is included in this distribution,
+in the file COPYING.GPL.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file
+does not by itself cause the resulting work to be covered
+by the GNU General Public License.
+
+However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+/** @file
+ * @brief provides wrapper and tools for signal related stuff.
+ *
+ *
+ * @copyright &copy; Copyright 2007-2008 by Intra2net AG
+ * @contact opensource@intra2net.com
+ *
+ * @bug 
+ * Although most stuff should work under most POSIX like systems;
+ * some funcs might be very linux related.
+ * (But at least we use that lib currently under linux only.)
+ */
+
+#ifndef _I2N_SIGNALFUNC_HPP_
+#define _I2N_SIGNALFUNC_HPP_
+
+#include <vector>
+
+// with pain in the stomach; the following include was added....:
+// (since these includes a lot of #define's... what we usually don't want to have in C++ headers...)
+#include <sys/types.h>
+
+extern "C"
+{
+
+struct siginfo;
+
+}
+
+
+namespace I2n
+{
+namespace SystemTools
+{
+
+
+namespace Detail
+{
+
+/**
+ * base class for internal implementation classes.
+ */
+class SObject
+{
+    public:
+        virtual ~SObject() {}
+}; // eo class SObject
+
+} // eo namespace Detail
+
+/**
+ * @brief representation of system signal.
+ *
+ * This struct also provides constants for the usual system signals; so it is not necessary to include signal.h
+ * for obtaining the constants.
+ *
+ * Due to an appropriate cast operator instances of the class can be used in all places where
+ * a plain signal (i.e. an int) is expected.
+ */
+struct Signal
+{
+    static const int VOID;
+/// @cond
+
+#define SIG(s) static const int s
+    SIG(HUP);   SIG(INT);   SIG(QUIT);  SIG(ILL);   SIG(TRAP);
+    SIG(ABRT);  SIG(IOT);   SIG(BUS);   SIG(FPE);   SIG(KILL);
+    SIG(USR1);  SIG(SEGV);  SIG(USR2);  SIG(PIPE);  SIG(ALRM);
+    SIG(TERM);  SIG(STKFLT); SIG(CLD);  SIG(CHLD);  SIG(CONT);  SIG(STOP);
+    SIG(TSTP);  SIG(TTIN);  SIG(TTOU);  SIG(URG);   SIG(XCPU);
+    SIG(XFSZ);  SIG(VTALRM); SIG(PROF); SIG(WINCH); SIG(POLL);
+    SIG(IO);    SIG(PWR);   SIG(SYS);
+#undef SIG
+
+/// @endcond
+
+    static int RT(int num=0);
+
+    int Value;
+
+    Signal(int signal) : Value(signal) {}
+
+    operator int () const { return Value; }
+}; // eo struct Signal
+
+
+/**
+ * @brief representation of signal codes.
+ *
+ * This struct provides constants for signal codes; so it is not necessary to include signal.h
+ * for obtaining the constants.
+ *
+ * Due to an appropriate cast operator instances of the class can be used in all places where
+ * a plain signal code (i.e. an int) is expected.
+ */
+struct SignalCode
+{
+
+
+/// @cond
+#define CODE(name) static const int name
+    CODE(USER);    CODE(QUEUE); CODE(TIMER); CODE(MESGQ);
+    CODE(ASYNCIO);
+#undef SIGIO
+    CODE(SIGIO);
+/// @endcond
+
+    /**
+     * @brief contains the codes for signal SIGILL
+     */
+    struct ILL
+    {
+        /// @cond
+        CODE(ILLOPC); CODE(ILLOPN); CODE(ILLADR); CODE(ILLTRP);
+        CODE(PRVOPC); CODE(PRVREG); CODE(COPROC); CODE(BADSTK);
+        /// @endcond
+    }; // eo struct ILL;
+
+
+    /**
+     * @brief contains the codes for signal SIGFPE
+     */
+    struct FPE
+    {
+        /// @cond
+        CODE(INTDIV); CODE(INTOVF); CODE(FLTDIV); CODE(FLTOVF);
+        CODE(FLTUND); CODE(FLTRES); CODE(FLTINV); CODE(FLTSUB);
+        /// @endcond
+    }; // eo struct FPE
+
+
+    /**
+     * @brief contains the codes for signal SIGSEGV
+     */
+    struct SEGV
+    {
+        /// @cond
+        CODE(MAPERR); CODE(ACCERR);
+        /// @endcond
+    }; // eo struct SEGV
+
+
+    /**
+     * @brief contains the codes for signal SIGBUS
+     */
+    struct BUS
+    {
+        /// @cond
+        CODE(ADRALN); CODE(ADRERR); CODE(OBJERR);
+        /// @endcond
+    }; // eo struct BUS
+
+
+    /**
+     * @brief contains the codes for signal SIGTRAP
+     */
+    struct TRAP
+    {
+        /// @cond
+        CODE(BRKPT); CODE(TRACE);
+        /// @endcond
+    }; // eo struct TRAP
+
+
+    /**
+     * @brief contains the codes for signal SIGCHLD
+     */
+    struct CHLD
+    {
+        /// @cond
+        CODE(EXITED); CODE(KILLED); CODE(DUMPED); CODE(TRAPPED);
+        CODE(STOPPED); CODE(CONTINUED);
+        /// @endcond
+    }; // eo struct CHLD
+
+
+    /**
+     * @brief contains the codes for signal SIGPOLL
+     */
+    struct POLL
+    {
+        /// @cond
+        CODE(IN); CODE(OUT); CODE(MSG); CODE(ERR); CODE(PRI); CODE(HUP);
+        /// @endcond
+    }; // eo strcut POLL
+
+#undef CODE
+
+    int TheCode;
+
+    SignalCode(int code) : TheCode(code) {}
+
+    operator int () const { return TheCode; }
+}; // eo SignalCode
+
+
+
+
+/**
+ * @brief helper for blocking a (or some) signal(s) during an operation.
+ *
+ * This class blocks the given signals when constructed and resets the original block mask
+ * when destructed.
+ */
+class ScopedSignalBlocker
+{
+    public:
+        ScopedSignalBlocker(Signal sig);
+        ScopedSignalBlocker(Signal sig1, Signal sig2);
+        ScopedSignalBlocker(Signal sig1, Signal sig2, Signal sig3);
+        ScopedSignalBlocker(const std::vector<Signal>& sigs);
+        virtual ~ScopedSignalBlocker();
+
+    private:
+        Detail::SObject* Implementation;
+
+}; // eo class ScopedSignalBlocker
+
+
+
+
+bool install_signal_handler(
+    Signal sig,
+    void(*handler)(int)
+);
+
+bool install_signal_handler(
+    Signal sig,
+    void(*handler)(int,struct siginfo*,void*)
+);
+
+bool ignore_signal(Signal sig);
+bool install_default_signal_handler(Signal sig);
+
+bool restore_signal_handler(Signal sig);
+
+
+bool send_signal( pid_t pid, Signal signal);
+
+
+} // eo namespace SysTools
+} // eo namespace I2n
+
+#endif