diff --git a/Utils/Console/Config.cc b/Utils/Console/Config.cc index 77d712ac4ba0b98803362e90209bfae1a3390abb..e6723aa53212633f3e30085132210f09b5e04fd5 100644 --- a/Utils/Console/Config.cc +++ b/Utils/Console/Config.cc @@ -120,9 +120,8 @@ prefix_ void senf::console::ConfigBundle::parse(DirectoryNode & restrict) prefix_ void senf::console::ConfigBundle::parseInternal() { - Sources::const_iterator i (sources_.begin()); - Sources::const_iterator const i_end (sources_.end()); - for (; i != i_end; ++i) + // It is valid to add additional sources at the end while parsing ... + for (Sources::const_iterator i (sources_.begin()); i != sources_.end(); ++i) (*i)->parse(executor_); } diff --git a/Utils/Console/Config.cci b/Utils/Console/Config.cci index 46cb12f9e8f3b534e9e546cfd9269d49b26415c6..99bccc8f0cb964be84aba43e20bf57c586d5a428 100644 --- a/Utils/Console/Config.cci +++ b/Utils/Console/Config.cci @@ -53,6 +53,11 @@ prefix_ senf::console::DirectoryNode & senf::console::detail::RestrictedExecutor return executor_.chroot(); } +prefix_ std::ostream & senf::console::detail::RestrictedExecutor::stream() +{ + return stream_; +} + /////////////////////////////////////////////////////////////////////////// // senf::console::ConfigBundle diff --git a/Utils/Console/Config.hh b/Utils/Console/Config.hh index 4ef6fb0c09b4db74b058730e6c74e9ad8e6e7e6a..64d9802f0609f42f9dadd32e2d6a8c27db4f5268 100644 --- a/Utils/Console/Config.hh +++ b/Utils/Console/Config.hh @@ -28,6 +28,7 @@ // Custom includes #include <boost/utility.hpp> +#include <list> #include "Parse.hh" #include "Executor.hh" @@ -94,7 +95,7 @@ namespace console { private: void parseInternal(); - typedef std::vector<detail::ConfigSource::ptr> Sources; + typedef std::list<detail::ConfigSource::ptr> Sources; Sources sources_; detail::RestrictedExecutor executor_; diff --git a/Utils/Console/Config.ih b/Utils/Console/Config.ih index bb0e55ecdf86aec21f43ae058e021c1d35f5264a..3c9ec54762c3c924c9beab4c19b680273520f9d8 100644 --- a/Utils/Console/Config.ih +++ b/Utils/Console/Config.ih @@ -31,6 +31,7 @@ #include <boost/intrusive_ptr.hpp> #include "Executor.hh" #include "../../Utils/intrusive_refcount.hh" +#include "../../Utils/DiscardStream.hh" ///////////////////////////////ih.p//////////////////////////////////////// @@ -77,6 +78,8 @@ namespace detail { DirectoryNode & root() const; + std::ostream & stream(); + class RestrictGuard; protected: @@ -90,6 +93,7 @@ namespace detail { Executor executor_; ParsedNodes parsedNodes_; DirectoryNode::ptr restrict_; + DiscardStream stream_; friend class RestrictGuard; }; diff --git a/Utils/Console/ConfigFile.cc b/Utils/Console/ConfigFile.cc index bbe3b3f92130250ba0f6ceff136cca081a346327..6674c4c45ba22b4705fe8e58deb207392ad496d1 100644 --- a/Utils/Console/ConfigFile.cc +++ b/Utils/Console/ConfigFile.cc @@ -39,7 +39,7 @@ prefix_ void senf::console::detail::ConfigFileSource::v_parse(RestrictedExecutor { try { parser_.parseFile(filename_, boost::bind( boost::ref(executor), - boost::ref(std::cerr), + boost::ref(executor.stream()), _1 )); } catch (SystemException & ex) { diff --git a/Utils/Console/Executor.cc b/Utils/Console/Executor.cc index 7733e072948b8b025cb0f702533932347d055628..e464906e330c2299be7e5776ef399d7122828be7 100644 --- a/Utils/Console/Executor.cc +++ b/Utils/Console/Executor.cc @@ -41,7 +41,7 @@ namespace { - struct TraverseTokens { + struct TraversTokens { typedef std::string const & result_type; result_type operator()(senf::console::Token const & token) const { return token.value(); @@ -140,11 +140,11 @@ prefix_ void senf::console::Executor::execute(std::ostream & output, } } - catch (InvalidPathException &) { - throw SyntaxErrorException("invalid path"); + catch (InvalidPathException & ex) { + throw SyntaxErrorException("invalid path") << " '" << ex.path << "'"; } - catch (InvalidDirectoryException &) { - throw SyntaxErrorException("invalid directory"); + catch (InvalidDirectoryException & ex) { + throw SyntaxErrorException("invalid directory") << " '" << ex.path << "'"; } catch (InvalidCommandException &) { throw SyntaxErrorException("invalid command"); @@ -297,7 +297,12 @@ senf::console::Executor::traverseNode(ParseCommandInfo::TokensRange const & path return dir.back().lock()->get(name); } catch (UnknownNodeNameException &) { - throw InvalidPathException(); + throw InvalidPathException( + senf::stringJoin( + senf::make_transform_range( + boost::make_iterator_range(path.begin(), path.end()), + boost::bind(&Token::value, _1)), + "/")); } } @@ -305,10 +310,14 @@ prefix_ void senf::console::Executor::traverseDirectory(ParseCommandInfo::TokensRange const & path, Path & dir) { + std::string errorPath; try { ParseCommandInfo::TokensRange::const_iterator i (path.begin()); ParseCommandInfo::TokensRange::const_iterator const i_end (path.end()); for (; i != i_end; ++i) { + if (i != path.begin()) + errorPath += "/"; + errorPath += i->value(); if (*i == NoneToken()) { if (i == path.begin()) { dir.clear(); diff --git a/Utils/Console/Executor.hh b/Utils/Console/Executor.hh index 6a950f0b2dacacbec58c8728460d645d0aca6164..9341dedee2d18bd77144eeaa632834ef360368cb 100644 --- a/Utils/Console/Executor.hh +++ b/Utils/Console/Executor.hh @@ -148,8 +148,17 @@ namespace console { Path & dir); std::string complete(DirectoryNode & dir, std::string const & name); - struct InvalidPathException {}; - struct InvalidDirectoryException {}; + struct InvalidPathException { + std::string path; + InvalidPathException() : path() {} + InvalidPathException(std::string path_) : path(path_) {} + + }; + struct InvalidDirectoryException { + std::string path; + InvalidDirectoryException() : path() {} + InvalidDirectoryException(std::string path_) : path(path_) {} + }; struct InvalidCommandException {}; DirectoryNode::ptr root_; diff --git a/Utils/Console/Parse.test.cc b/Utils/Console/Parse.test.cc index 7f85ac747295e8e70a22b429829816ec763f2a31..57fb9889c81818dce023c5e21d20581e2b9a4776 100644 --- a/Utils/Console/Parse.test.cc +++ b/Utils/Console/Parse.test.cc @@ -85,7 +85,7 @@ BOOST_AUTO_UNIT_TEST(commandGrammar) { static char text[] = "# Comment\n" - "doo / bii / doo arg" + "doo/bii/doo arg/two/three" " flab::blub" " 123.434>a" " (a,b;c (huhu/{haha}))" @@ -99,7 +99,7 @@ BOOST_AUTO_UNIT_TEST(commandGrammar) grammar.use_parser<Grammar::SkipParser>() ) . full ); BOOST_CHECK_EQUAL( ss.str(), "beginCommand( Word('doo')/Word('bii')/Word('doo') )\n" - "pushToken( Word('arg') )\n" + "pushToken( Word('arg/two/three') )\n" "pushToken( Word('flab::blub') )\n" "pushToken( Word('123.434>a') )\n" "pushToken( ArgumentGroupOpen('(') )\n" diff --git a/Utils/Console/ProgramOptions.cc b/Utils/Console/ProgramOptions.cc index 0efbd7e36b00ee07600ab5adfb759a802fddac10..245cce36f9a3d07933230767f526ef6809ad3848 100644 --- a/Utils/Console/ProgramOptions.cc +++ b/Utils/Console/ProgramOptions.cc @@ -152,7 +152,7 @@ senf::console::detail::ProgramOptionsSource::parseLongOption(std::string const & cmd.command(path); parser_.parseArguments(value, cmd); - executor(std::cerr, cmd); + executor(executor.stream(), cmd); } prefix_ void diff --git a/Utils/Console/Server.ih b/Utils/Console/Server.ih index 5e110faaab2516430b21671454b1f59cf3e9465d..d97c1c9c60fdbe2dce125144c1916b4cb78a7b56 100644 --- a/Utils/Console/Server.ih +++ b/Utils/Console/Server.ih @@ -70,11 +70,6 @@ namespace detail { : public boost::iostreams::sink { public: - typedef ClientSocketHandle< - senf::MakeSocketPolicy<StreamFramingPolicy, - WriteablePolicy, - ConnectedCommunicationPolicy>::policy > Handle; - NonblockingSocketSink(Client & client); std::streamsize write(const char * s, std::streamsize n); diff --git a/Utils/DiscardStream.cci b/Utils/DiscardStream.cci new file mode 100644 index 0000000000000000000000000000000000000000..dcdd535e1f419b81dd5146c20109326b978327d0 --- /dev/null +++ b/Utils/DiscardStream.cci @@ -0,0 +1,55 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund <g0dil@berlios.de> +// +// 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; either version 2 of the License, or +// (at your option) any later version. +// +// 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., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief DiscardStream inline non-template implementation */ + +//#include "DiscardStream.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +prefix_ std::streamsize senf::DiscardSink::write(char const * s, std::streamsize n) +{ + return n; +} + +prefix_ senf::DiscardStream::DiscardStream() +{ + open(DiscardSink()); +} + +///////////////////////////////cci.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Utils/DiscardStream.hh b/Utils/DiscardStream.hh new file mode 100644 index 0000000000000000000000000000000000000000..de4823b357b10adcda9112a1c6dcf5acf382ec94 --- /dev/null +++ b/Utils/DiscardStream.hh @@ -0,0 +1,69 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund <g0dil@berlios.de> +// +// 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; either version 2 of the License, or +// (at your option) any later version. +// +// 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., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief DiscardStream public header */ + +#ifndef HH_SENF_Utils_DiscardStream_ +#define HH_SENF_Utils_DiscardStream_ 1 + +// Custom includes +#include <boost/iostreams/concepts.hpp> +#include <boost/iostreams/stream.hpp> + +//#include "DiscardStream.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { + + class DiscardSink + : public boost::iostreams::sink + { + public: + std::streamsize write(char const * s, std::streamsize n); + }; + + class DiscardStream + : public boost::iostreams::stream<DiscardSink> + { + public: + DiscardStream(); + }; + +} + +///////////////////////////////hh.e//////////////////////////////////////// +#include "DiscardStream.cci" +//#include "DiscardStream.ct" +//#include "DiscardStream.cti" +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Utils/DiscardStream.test.cc b/Utils/DiscardStream.test.cc new file mode 100644 index 0000000000000000000000000000000000000000..82144576fd36762e32118b08f76f2171322f91f2 --- /dev/null +++ b/Utils/DiscardStream.test.cc @@ -0,0 +1,56 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund <g0dil@berlios.de> +// +// 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; either version 2 of the License, or +// (at your option) any later version. +// +// 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., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief DiscardStream.test unit tests */ + +//#include "DiscardStream.test.hh" +//#include "DiscardStream.test.ih" + +// Custom includes +#include "DiscardStream.hh" + +#include "../Utils/auto_unit_test.hh" +#include <boost/test/test_tools.hpp> + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +BOOST_AUTO_UNIT_TEST(discardStream) +{ + senf::DiscardStream stream; + SENF_CHECK_NO_THROW( stream << "discard me" ); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Utils/Logger/AreaRegistry.cc b/Utils/Logger/AreaRegistry.cc index 7a6a98856be59b9403a95e3948d3e270095dc1a9..11bec47221d3c40162371c1b460a874652db681c 100644 --- a/Utils/Logger/AreaRegistry.cc +++ b/Utils/Logger/AreaRegistry.cc @@ -36,9 +36,15 @@ /////////////////////////////////////////////////////////////////////////// // senf::log::detail::AreaBase -prefix_ senf::log::detail::AreaBase::~AreaBase() +prefix_ senf::log::detail::AreaBase::AreaBase() + : alive_ (true) {} +prefix_ senf::log::detail::AreaBase::~AreaBase() +{ + alive_ = false; +} + prefix_ void senf::log::detail::AreaBase::updateRoutingCache(Target & target, StreamBase const & stream, unsigned limit) diff --git a/Utils/Logger/AreaRegistry.cci b/Utils/Logger/AreaRegistry.cci index 76e6e516d83a93f804a2a843fac21bddc2c29497..158c0079ea16c3edd100e591618f83bc68d50c0b 100644 --- a/Utils/Logger/AreaRegistry.cci +++ b/Utils/Logger/AreaRegistry.cci @@ -88,6 +88,12 @@ prefix_ void senf::log::detail::AreaBase::init() senf::log::AreaRegistry::instance().registerArea(*this); } +prefix_ bool senf::log::detail::AreaBase::alive() + const +{ + return alive_; +} + prefix_ unsigned senf::log::detail::AreaBase::limit(StreamBase const & stream) const { diff --git a/Utils/Logger/AreaRegistry.ih b/Utils/Logger/AreaRegistry.ih index 53b3d1009e08de77f44d0f555f01e39f446207ba..d5cd80956d1ae827d6a74fe9053b30bbcfa1ca8f 100644 --- a/Utils/Logger/AreaRegistry.ih +++ b/Utils/Logger/AreaRegistry.ih @@ -47,12 +47,14 @@ namespace detail { /** \brief Internal: Area base class */ struct AreaBase { + AreaBase(); virtual ~AreaBase(); std::string fullName() const; virtual std::string v_name() const; void init(); + bool alive() const; unsigned limit(StreamBase const & stream) const; void updateRoutingCache(Target & target, StreamBase const & stream, unsigned limit) const; @@ -74,6 +76,7 @@ namespace detail { }; typedef std::vector<CacheEntry> RoutingCache; mutable RoutingCache routingCache_; + bool alive_; }; }}} diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc index 16b00ff293044966af693f9d07b7a65e377b2b9c..7896bf0787983a9ad2911a80776f00728bdc8009 100644 --- a/Utils/Logger/Target.cc +++ b/Utils/Logger/Target.cc @@ -272,6 +272,9 @@ prefix_ void senf::log::Target::updateRoutingCache(detail::StreamBase const * st updateRoutingCache(stream, i->second); return; } + if (! area->alive()) + // We are globally destructing and the area is gone already ... + return; unsigned limit (DISABLED::value); RIB::iterator i (rib_.begin()); RIB::iterator const i_end (rib_.end()); @@ -415,7 +418,7 @@ prefix_ senf::log::detail::TargetRegistry::TargetRegistry() " <Directory '/sys/log/client-xxx.xxx.xxx.xxx:xxx'>\n" "\n" "Route all messages to the currently connected client\n" - " $ /sys/log/self { route (); }"); + " $ /sys/log/self { route (); }"); } prefix_ senf::log::detail::TargetRegistry::~TargetRegistry() diff --git a/Utils/auto_unit_test.hh b/Utils/auto_unit_test.hh index 8b0e1bbec3aae6cd5e3d1e49702589eaf8fdcf76..c12bb7d90e7c8d41e52fbe306703dfc8408ee5ce 100644 --- a/Utils/auto_unit_test.hh +++ b/Utils/auto_unit_test.hh @@ -37,6 +37,7 @@ #define HH_SENF_Utils_auto_unit_test_ 1 // Custom includes +#include <iostream> #include <boost/version.hpp> //#include "auto_unit_test.mpp"