X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FServer.cc;h=4e37e68c403709ed6e4bbbf92b53716ccfeba385;hb=9c0078ac0054789badff2a987364ed0448b080ef;hp=0fd831d5435d755c4c118668e069593a04fc5f95;hpb=826e50343096b75247521f6593cb78eb8c01615b;p=senf.git diff --git a/Console/Server.cc b/Console/Server.cc index 0fd831d..4e37e68 100644 --- a/Console/Server.cc +++ b/Console/Server.cc @@ -24,7 +24,7 @@ \brief Server non-inline non-template implementation */ #include "Server.hh" -#include "Server.ih" +//#include "Server.ih" // Custom includes #include @@ -32,6 +32,7 @@ #include #include #include +#include #include "../Utils/senfassert.hh" #include "../Utils/membind.hh" #include "../Utils/Logger/SenfLog.hh" @@ -40,55 +41,57 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ void senf::console::start(senf::INet4SocketAddress const & address) +prefix_ senf::console::Server & +senf::console::Server::start(senf::INet4SocketAddress const & address) { senf::TCPv4ServerSocketHandle handle (address); - handle.protocol().reuseaddr(); - senf::console::detail::Server::start(handle); - SENF_LOG((detail::Server::SENFLogArea)(log::NOTICE)( + senf::console::Server::start(handle); + SENF_LOG((Server::SENFLogArea)(log::NOTICE)( "Console server started at " << address )); + return *instance_; } -prefix_ void senf::console::start(senf::INet6SocketAddress const & address) +prefix_ senf::console::Server & +senf::console::Server::start(senf::INet6SocketAddress const & address) { senf::TCPv6ServerSocketHandle handle (address); - handle.protocol().reuseaddr(); - senf::console::detail::Server::start(handle); - SENF_LOG((detail::Server::SENFLogArea)(log::NOTICE)( + senf::console::Server::start(handle); + SENF_LOG((Server::SENFLogArea)(log::NOTICE)( "Console server started at " << address )); + return *instance_; } /////////////////////////////////////////////////////////////////////////// -// senf::console::detail::Server +// senf::console::Server -boost::scoped_ptr senf::console::detail::Server::instance_; +boost::scoped_ptr senf::console::Server::instance_; -prefix_ void senf::console::detail::Server::start(ServerHandle handle) +prefix_ void senf::console::Server::start(ServerHandle handle) { SENF_ASSERT( ! instance_ ); instance_.reset(new Server(handle)); } -prefix_ senf::console::detail::Server::Server(ServerHandle handle) +prefix_ senf::console::Server::Server(ServerHandle handle) : handle_ (handle) { Scheduler::instance().add( handle_, senf::membind(&Server::newClient, this) ); } -prefix_ senf::console::detail::Server::~Server() +prefix_ senf::console::Server::~Server() { Scheduler::instance().remove(handle_); } -prefix_ void senf::console::detail::Server::newClient(Scheduler::EventId event) +prefix_ void senf::console::Server::newClient(Scheduler::EventId event) { ServerHandle::ClientSocketHandle client (handle_.accept()); - boost::intrusive_ptr p (new Client(client)); + boost::intrusive_ptr p (new Client(client, name_)); clients_.insert( p ); SENF_LOG(( "Registered new client " << p.get() )); } -prefix_ void senf::console::detail::Server::removeClient(Client & client) +prefix_ void senf::console::Server::removeClient(Client & client) { SENF_LOG(( "Disposing client " << & client )); // THIS DELETES THE CLIENT INSTANCE !! @@ -96,26 +99,26 @@ prefix_ void senf::console::detail::Server::removeClient(Client & client) } /////////////////////////////////////////////////////////////////////////// -// senf::console::detail::Client +// senf::console::Client -prefix_ senf::console::detail::Client::Client(ClientHandle handle) - : handle_ (handle), out_(::dup(handle.fd())) +prefix_ senf::console::Client::Client(ClientHandle handle, std::string const & name) + : handle_ (handle), name_ (name), out_(::dup(handle.fd())) { - out_ << "# " << std::flush; + showPrompt(); ReadHelper::dispatch( handle_, 16384u, ReadUntil("\n"), senf::membind(&Client::clientData, this) ); } -prefix_ senf::console::detail::Client::~Client() +prefix_ senf::console::Client::~Client() {} -prefix_ void senf::console::detail::Client::stopClient() +prefix_ void senf::console::Client::stopClient() { // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER removeClient RETURNS Server::instance_->removeClient(*this); } -prefix_ void senf::console::detail::Client::clientData(ReadHelper::ptr helper) +prefix_ void senf::console::Client::clientData(ReadHelper::ptr helper) { if (helper->error() || handle_.eof()) { // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER stopClient RETURNS @@ -123,26 +126,36 @@ prefix_ void senf::console::detail::Client::clientData(ReadHelper: return; } -# warning fix Client::clientData implementation - // Remove the 'dup' needed here so we don't close the same fd twice (see Client constructor) - // Make output non-blocking - // Don't register a new ReadHelper every round - std::string data (tail_ + helper->data()); tail_ = helper->tail(); boost::trim(data); // Gets rid of superfluous \r or \n characters - ParseCommandInfo command; - if (parser_.parseCommand(data, command)) - executor_(command, out_); - else - out_ << "syntax error" << std::endl; + try { + if (! parser_.parse(data, boost::bind(boost::ref(executor_), _1, boost::ref(out_)))) + out_ << "syntax error" << std::endl; + } + catch (Executor::ExitException &) { + // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER stopClient RETURNS + stopClient(); + return; + } + catch (std::exception & ex) { + out_ << ex.what() << std::endl; + } + catch (...) { + out_ << "unidentified error (unknown exception thrown)" << std::endl; + } - out_ << "# " << std::flush; + showPrompt(); ReadHelper::dispatch( handle_, 16384u, ReadUntil("\n"), senf::membind(&Client::clientData, this) ); } +prefix_ void senf::console::Client::showPrompt() +{ + out_ << name_ << ":" << executor_.cwd().path() << "# " << std::flush; +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "Server.mpp"