From 95133eff57efb462ae4d4cbdb27bc37a000345d2 Mon Sep 17 00:00:00 2001 From: Massimo Gengarelli Date: Tue, 1 May 2012 19:44:22 +0200 Subject: [PATCH] Added a Signal Handler In order to prevent the user to ^C while downloading a file (thus, risking to have an incoherent situation and prevent a bad behaviour of grive), it's necessary to register some signals. These two classes provide a wrapper around the C function signal, with facilities to register and unregister signals.. --- src/lib/util/SignalHandler.cc | 100 +++++++++++++++++++++++++++++++++ src/lib/util/SignalHandler.hh | 62 ++++++++++++++++++++ test/UnitTest.cc | 2 + test/util/SignalHandlerTest.cc | 51 +++++++++++++++++ test/util/SignalHandlerTest.hh | 41 ++++++++++++++ 5 files changed, 256 insertions(+) create mode 100644 src/lib/util/SignalHandler.cc create mode 100644 src/lib/util/SignalHandler.hh create mode 100644 test/util/SignalHandlerTest.cc create mode 100644 test/util/SignalHandlerTest.hh diff --git a/src/lib/util/SignalHandler.cc b/src/lib/util/SignalHandler.cc new file mode 100644 index 0000000..43328ee --- /dev/null +++ b/src/lib/util/SignalHandler.cc @@ -0,0 +1,100 @@ +/* + grive: an GPL program to sync a local directory with Google Drive + Copyright (C) 2012 Wan Wai Ho + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation version 2 + of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + +#include "SignalHandler.hh" +#include +#include +#include +#include +#include + +namespace gr { + +SignalError::SignalError( const std::string& message ) : + std::runtime_error( message ) +{ +} + +SignalError::~SignalError() throw () +{ + +} + +SignalHandler::SignalHandler() +{ + +} + +SignalHandler::SignalHandler( const SignalHandler& right ) +{ + +} + +SignalHandler& SignalHandler::operator ==( const SignalHandler& right ) +{ + return (*this); +} + +SignalHandler::~SignalHandler() +{ + +} + +SignalHandler& SignalHandler::GetInstance() +{ + static SignalHandler _instance; + return _instance; +} + +void SignalHandler::UnregisterSignal( unsigned int signumber ) +{ + m_signals[signumber] = 0 ; + + // Restore the old signal + signal( ( int ) signumber, m_signalsOld[signumber] ); +} + +void SignalHandler::RegisterSignal( unsigned int signumber, Callback callback ) +{ + signals_t::const_iterator anIterator ; + for (anIterator = m_signals.begin(); anIterator != m_signals.end(); ++anIterator) + { + if (anIterator->first == signumber) + { + if (anIterator->second != 0) + { + std::ostringstream oss; + oss << "Signal " << signumber << " already has a callback!"; + throw SignalError( oss.str() ); ; + } + } + } + + m_signals[signumber] = callback ; + + if ( ( m_signalsOld[signumber] = signal( ( int ) signumber, m_signals[signumber] ) ) == SIG_ERR ) { + throw SignalError( " Error while registering the signal! " ) ; + } +} + +} + + + diff --git a/src/lib/util/SignalHandler.hh b/src/lib/util/SignalHandler.hh new file mode 100644 index 0000000..2ef0867 --- /dev/null +++ b/src/lib/util/SignalHandler.hh @@ -0,0 +1,62 @@ +/* + grive: an GPL program to sync a local directory with Google Drive + Copyright (C) 2012 Wan Wai Ho + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation version 2 + of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include +#include +#include + +namespace gr { + +class SignalError : public std::runtime_error +{ +public : + SignalError( const std::string& message ) ; + virtual ~SignalError() throw () ; +}; + +class SignalFunctor +{ +public : + SignalFunctor() ; + virtual ~SignalFunctor() ; + static void Callback( int signumber ) ; +}; + +class SignalHandler +{ + typedef void (*Callback)(int); + typedef std::map signals_t ; + +public : + virtual ~SignalHandler() ; + void RegisterSignal ( unsigned int signumber, Callback callback ) ; + void UnregisterSignal( unsigned int signumber ); + static SignalHandler& GetInstance() ; +private : + SignalHandler() ; + SignalHandler( const SignalHandler& right ) ; + SignalHandler& operator==( const SignalHandler& right ) ; + + signals_t m_signals; + signals_t m_signalsOld; +}; + +} diff --git a/test/UnitTest.cc b/test/UnitTest.cc index 3343354..4670ced 100644 --- a/test/UnitTest.cc +++ b/test/UnitTest.cc @@ -22,6 +22,7 @@ #include "util/DateTimeTest.hh" #include "util/FunctionTest.hh" #include "util/PathTest.hh" +#include "util/SignalHandlerTest.hh" int main( int argc, char **argv ) { @@ -31,6 +32,7 @@ int main( int argc, char **argv ) runner.addTest( DateTimeTest::suite( ) ) ; runner.addTest( FunctionTest::suite( ) ) ; runner.addTest( PathTest::suite( ) ) ; + runner.addTest( SignalHandlerTest::suite( ) ) ; runner.run(); return 0 ; diff --git a/test/util/SignalHandlerTest.cc b/test/util/SignalHandlerTest.cc new file mode 100644 index 0000000..c7110d7 --- /dev/null +++ b/test/util/SignalHandlerTest.cc @@ -0,0 +1,51 @@ +/* + grive: an GPL program to sync a local directory with Google Drive + Copyright (C) 2012 Wan Wai Ho + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation version 2 + of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "SignalHandlerTest.hh" + +#include "util/SignalHandler.hh" + +#include + +void test_callback( int ) +{ + +} + +namespace grut { + +using namespace gr ; + +SignalHandlerTest::SignalHandlerTest( ) +{ +} + +void SignalHandlerTest::TestMultipleSignals( ) +{ + SignalHandler::GetInstance().RegisterSignal( SIGINT, &test_callback ); + CPPUNIT_ASSERT_THROW( + SignalHandler::GetInstance().RegisterSignal( SIGINT, &test_callback ), + SignalError); + + SignalHandler::GetInstance().UnregisterSignal( SIGINT ); + CPPUNIT_ASSERT_NO_THROW( + SignalHandler::GetInstance().RegisterSignal( SIGINT, &test_callback )); +} + +} diff --git a/test/util/SignalHandlerTest.hh b/test/util/SignalHandlerTest.hh new file mode 100644 index 0000000..81d6232 --- /dev/null +++ b/test/util/SignalHandlerTest.hh @@ -0,0 +1,41 @@ +/* + grive: an GPL program to sync a local directory with Google Drive + Copyright (C) 2012 Wan Wai Ho + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation version 2 + of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include +#include + +namespace grut { + +class SignalHandlerTest : public CppUnit::TestFixture +{ +public : + SignalHandlerTest( ) ; + + // declare suit function + CPPUNIT_TEST_SUITE( SignalHandlerTest ) ; + CPPUNIT_TEST( TestMultipleSignals ) ; + CPPUNIT_TEST_SUITE_END(); + +private : + void TestMultipleSignals( ) ; +} ; + +} // end of namespace