#include "Server.ih"
// Custom includes
+#include <errno.h>
#include <iostream>
#include <boost/algorithm/string/trim.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include "../../Utils/membind.hh"
#include "../../Utils/Logger/SenfLog.hh"
#include "LineEditor.hh"
+#include "ScopedDirectory.hh"
+#include "Sysdir.hh"
+#include "ParsedCommand.hh"
//#include "Server.mpp"
#define prefix_
: handle_ (handle),
event_ ("senf::console::Server", senf::membind(&Server::newClient, this),
handle_, scheduler::FdEvent::EV_READ),
- root_ (senf::console::root().thisptr()), mode_ (Automatic)
+ root_ (senf::console::root().thisptr()), mode_ (Automatic),
+ name_ (::program_invocation_short_name)
{}
prefix_ void senf::console::Server::newClient(int event)
ServerHandle::ClientHandle client (handle_.accept());
boost::intrusive_ptr<Client> p (new Client(*this, client));
clients_.insert( p );
- SENF_LOG(( "Registered new client " << p.get() ));
+ SENF_LOG(( "Registered new client " << client.peer() ));
}
prefix_ void senf::console::Server::removeClient(Client & client)
{
- SENF_LOG(( "Disposing client " << & client ));
+ SENF_LOG(( "Disposing client " << client.handle().peer() ));
// THIS DELETES THE CLIENT INSTANCE !!
clients_.erase(boost::intrusive_ptr<Client>(&client));
}
// senf::console::Client
prefix_ senf::console::Client::Client(Server & server, ClientHandle handle)
- : out_t(boost::ref(*this)), senf::log::IOStreamTarget(out_t::member), server_ (server),
- handle_ (handle),
+ : out_t(boost::ref(*this)),
+ senf::log::IOStreamTarget("client-" + senf::str(handle.peer()), out_t::member),
+ server_ (server), handle_ (handle),
readevent_ ("senf::console::Client::interactive_check",
boost::bind(&Client::setNoninteractive,this),
handle, scheduler::FdEvent::EV_READ, false),
_1 ));
}
catch (Executor::ExitException &) {
- // This generates an EOF condition on the Handle. This EOF condition is expected
- // to be handled gracefully by the ClientReader. We cannot call stop() here, since we
- // are called from the client reader callback and that will continue executing even if we
- // call stop here ...
+ // This generates an EOF condition on the Handle. This EOF condition is expected to be
+ // handled gracefully by the ClientReader. We cannot call stop() here, since we are called
+ // from the client reader callback and that will continue executing after stop() has been
+ // called. stop() however will delete *this instance ... BANG ...
handle_.facet<senf::TCPSocketProtocol>().shutdown(senf::TCPSocketProtocol::ShutRD);
}
catch (std::exception & ex) {
- stream() << ex.what() << std::endl;
+ std::string msg (ex.what());
+ std::string::size_type i (msg.find("-- \n"));
+ if (i != std::string::npos) {
+ backtrace_ = msg.substr(0,i);
+ msg = msg.substr(i+4);
+ } else
+ backtrace_.clear();
+ stream() << msg << std::endl;
}
catch (...) {
stream() << "unidentified error (unknown exception thrown)" << std::endl;
reader_->enablePrompt();
}
-prefix_ std::ostream & senf::console::operator<<(std::ostream & os, Client const & client)
-{
- typedef ClientSocketHandle< MakeSocketPolicy<
- INet4AddressingPolicy,ConnectedCommunicationPolicy>::policy > V4Socket;
- typedef ClientSocketHandle< MakeSocketPolicy<
- INet6AddressingPolicy,ConnectedCommunicationPolicy>::policy > V6Socket;
+///////////////////////////////////////////////////////////////////////////
+// senf::console::Client::SysBacktrace
- try {
- if (check_socket_cast<V4Socket>(client.handle()))
- os << dynamic_socket_cast<V4Socket>(client.handle()).peer();
- else if (check_socket_cast<V6Socket>(client.handle()))
- os << dynamic_socket_cast<V6Socket>(client.handle()).peer();
- else
- os << static_cast<void const *>(&client);
- }
- catch (SystemException &) {
- os << "0.0.0.0:0";
- }
-
- return os;
+prefix_ senf::console::Client::SysBacktrace::SysBacktrace()
+{
+ sysdir().node().add("backtrace", &SysBacktrace::backtrace)
+ .doc("Display the backtrace of the last error / exception in this console");
}
-prefix_ std::ostream & senf::console::operator<<(std::ostream & os, Client * client)
+prefix_ void senf::console::Client::SysBacktrace::backtrace(std::ostream & os)
{
- return os << *client;
+ Client & client (Client::get(os));
+ if (client.backtrace().empty())
+ os << "(no backtrace)";
+ else
+ os << client.backtrace();
}
+senf::console::Client::SysBacktrace senf::console::Client::SysBacktrace::instance_;
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "Server.mpp"