Skip to content
Snippets Groups Projects
Commit 7c8482ff authored by g0dil's avatar g0dil
Browse files

Console: Implement current directory management and builtins (cd, dirstack, ls)

parent 67838f8c
No related branches found
No related tags found
No related merge requests found
...@@ -38,13 +38,81 @@ ...@@ -38,13 +38,81 @@
prefix_ bool senf::console::Executor::operator()(ParseCommandInfo const & command, prefix_ bool senf::console::Executor::operator()(ParseCommandInfo const & command,
std::ostream & output) std::ostream & output)
{ {
# warning Implement Executor::operator()
SENF_LOG(( "Executing: " << command )); SENF_LOG(( "Executing: " << command ));
if (command.builtin() == ParseCommandInfo::BuiltinEXIT)
if (cwd_.expired())
cwd_ = boost::static_pointer_cast<DirectoryNode>(
root().shared_from_this());
switch(command.builtin()) {
case ParseCommandInfo::NoBuiltin :
break;
case ParseCommandInfo::BuiltinCD :
if ( command.arguments() &&
! chdir(command.arguments().begin()[0]) )
output << "invalid directory\n";
break;
case ParseCommandInfo::BuiltinLS :
for (DirectoryNode::child_iterator i (cwd().children().begin());
i != cwd().children().end(); ++i)
output << i->first << "\n";
break;
case ParseCommandInfo::BuiltinPUSHD :
dirstack_.push_back(cwd_);
if ( command.arguments()
&& ! chdir(command.arguments().begin()[0]) )
output << "invalid directory\n";
break;
case ParseCommandInfo::BuiltinPOPD :
if (! dirstack_.empty()) {
cwd_ = dirstack_.back();
dirstack_.pop_back();
}
break;
case ParseCommandInfo::BuiltinEXIT :
throw ExitException(); throw ExitException();
}
return true; return true;
} }
prefix_ bool senf::console::Executor::chdir(ParseCommandInfo::argument_value_type const & path)
{
try {
DirectoryNode::ptr dir (cwd_.lock());
ParseCommandInfo::token_iterator i (path.begin());
ParseCommandInfo::token_iterator const i_end (path.end());
if (i != i_end && i->value().empty()) {
dir = boost::static_pointer_cast<DirectoryNode>(
root().shared_from_this());
++ i;
}
for (; i != i_end; ++i) {
if (i->value() == "..") {
dir = dir->parent();
if (! dir)
dir = boost::static_pointer_cast<DirectoryNode>(
root().shared_from_this());
}
else if (! i->value().empty() && i->value() != ".")
dir = boost::static_pointer_cast<DirectoryNode>(
(*dir)[i->value()].shared_from_this());
}
cwd_ = dir;
}
catch (std::bad_cast &) {
return false;
}
catch (UnknownNodeNameException &) {
return false;
}
return true;
}
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_ #undef prefix_
//#include "Executor.mpp" //#include "Executor.mpp"
......
// $Id$
//
// Copyright (C) 2008
// 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 Executor inline non-template implementation */
//#include "Executor.ih"
// Custom includes
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::console::Executor
prefix_ senf::console::Executor::Executor()
{
cwd_ = boost::static_pointer_cast<DirectoryNode>(
root().shared_from_this());
}
prefix_ senf::console::DirectoryNode & senf::console::Executor::cwd()
const
{
return cwd_.expired() ? root() : *cwd_.lock();
}
///////////////////////////////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:
...@@ -27,8 +27,10 @@ ...@@ -27,8 +27,10 @@
#define HH_Executor_ 1 #define HH_Executor_ 1
// Custom includes // Custom includes
#include <boost/utility.hpp>
#include "Parse.hh" #include "Parse.hh"
#include "../Utils/Logger/SenfLog.hh" #include "../Utils/Logger/SenfLog.hh"
#include "Node.hh"
//#include "Executor.mpp" //#include "Executor.mpp"
///////////////////////////////hh.p//////////////////////////////////////// ///////////////////////////////hh.p////////////////////////////////////////
...@@ -39,6 +41,7 @@ namespace console { ...@@ -39,6 +41,7 @@ namespace console {
/** \brief /** \brief
*/ */
class Executor class Executor
: boost::noncopyable
{ {
SENF_LOG_CLASS_AREA(); SENF_LOG_CLASS_AREA();
SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE ); SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
...@@ -51,20 +54,32 @@ namespace console { ...@@ -51,20 +54,32 @@ namespace console {
struct ExitException {}; // NOT derived from std::exception ! struct ExitException {}; // NOT derived from std::exception !
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
//\/name Structors and default members
///\{
Executor();
///\}
///////////////////////////////////////////////////////////////////////////
bool operator()(ParseCommandInfo const & command, std::ostream & output); bool operator()(ParseCommandInfo const & command, std::ostream & output);
DirectoryNode & cwd() const;
protected: protected:
private: private:
bool chdir(ParseCommandInfo::argument_value_type const & path);
DirectoryNode::weak_ptr cwd_;
typedef std::vector<DirectoryNode::weak_ptr> DirStack;
DirStack dirstack_;
}; };
}} }}
///////////////////////////////hh.e//////////////////////////////////////// ///////////////////////////////hh.e////////////////////////////////////////
//#include "Executor.cci" #include "Executor.cci"
//#include "Executor.ct" //#include "Executor.ct"
//#include "Executor.cti" //#include "Executor.cti"
#endif #endif
......
...@@ -32,11 +32,33 @@ ...@@ -32,11 +32,33 @@
#define prefix_ #define prefix_
///////////////////////////////cc.p//////////////////////////////////////// ///////////////////////////////cc.p////////////////////////////////////////
prefix_ senf::console::DirectoryNode & senf::console::root()
{
static DirectoryNode::ptr rootNode(new DirectoryNode(""));
return *rootNode;
}
///////////////////////////////////////////////////////////////////////////
// senf::console::GenericNode
prefix_ std::string senf::console::GenericNode::path()
const
{
std::string path (name());
ptr node (parent());
while (node) {
path = node->name() + "/" + path;
node = node->parent();
}
return path.empty() ? "/" : path;
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
//senf::console::DirectoryNode //senf::console::DirectoryNode
prefix_ void senf::console::DirectoryNode::add(GenericNode::ptr node, bool uniquify) prefix_ void senf::console::DirectoryNode::add(GenericNode::ptr node, bool uniquify)
{ {
BOOST_ASSERT( ! node->parent() );
if (children_.find(node->name()) != children_.end()) { if (children_.find(node->name()) != children_.end()) {
if (! uniquify) if (! uniquify)
throw DuplicateNodeNameException() << ": '" << node->name() << "'"; throw DuplicateNodeNameException() << ": '" << node->name() << "'";
...@@ -49,6 +71,7 @@ prefix_ void senf::console::DirectoryNode::add(GenericNode::ptr node, bool uniqu ...@@ -49,6 +71,7 @@ prefix_ void senf::console::DirectoryNode::add(GenericNode::ptr node, bool uniqu
name(*node, newName); name(*node, newName);
} }
children_.insert(std::make_pair(node->name(),node)); children_.insert(std::make_pair(node->name(),node));
node->parent_ = this;
} }
prefix_ senf::console::GenericNode & prefix_ senf::console::GenericNode &
......
...@@ -34,14 +34,17 @@ ...@@ -34,14 +34,17 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::console::GenericNode // senf::console::GenericNode
prefix_ senf::console::GenericNode::~GenericNode()
{}
prefix_ std::string const & senf::console::GenericNode::name() prefix_ std::string const & senf::console::GenericNode::name()
const const
{ {
return name_; return name_;
} }
prefix_ senf::console::GenericNode::GenericNode(std::string const & name, bool managed) prefix_ senf::console::GenericNode::GenericNode(std::string const & name)
: name_ (name), managed_ (managed) : name_ (name), parent_ (0)
{} {}
prefix_ void senf::console::GenericNode::name(std::string const & name) prefix_ void senf::console::GenericNode::name(std::string const & name)
...@@ -54,38 +57,22 @@ prefix_ void senf::console::GenericNode::name(GenericNode & node, std::string co ...@@ -54,38 +57,22 @@ prefix_ void senf::console::GenericNode::name(GenericNode & node, std::string co
node.name_ = name; node.name_ = name;
} }
prefix_ senf::console::DirectoryNode & senf::console::GenericNode::parent() prefix_ boost::shared_ptr<senf::console::DirectoryNode> senf::console::GenericNode::parent()
const
{
SENF_ASSERT( parent_ );
return *parent_;
}
prefix_ bool senf::console::GenericNode::managed()
const const
{ {
return managed_; return boost::static_pointer_cast<DirectoryNode>(
} parent_ ? parent_->shared_from_this() : ptr() );
prefix_ bool senf::console::GenericNode::release()
{
// Beware ! call release() first so the call is not short-circuited way !
return intrusive_refcount_base::release() && managed_;
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::console::DirectoryNode // senf::console::DirectoryNode
prefix_ void senf::console::DirectoryNode::add(std::auto_ptr<GenericNode> node, bool uniquify) prefix_ senf::console::GenericNode &
{ senf::console::DirectoryNode::add(std::auto_ptr<GenericNode> node, bool uniquify)
SENF_ASSERT( node->managed() );
add(GenericNode::ptr(node.release()), uniquify);
}
prefix_ void senf::console::DirectoryNode::add(GenericNode & node, bool uniquify)
{ {
SENF_ASSERT( ! node.managed() ); GenericNode::ptr p (node.release());
add(GenericNode::ptr(&node),uniquify); add(p, uniquify);
return *p;
} }
prefix_ senf::console::DirectoryNode & prefix_ senf::console::DirectoryNode &
...@@ -102,15 +89,28 @@ senf::console::DirectoryNode::operator()(std::string const & name) ...@@ -102,15 +89,28 @@ senf::console::DirectoryNode::operator()(std::string const & name)
return dynamic_cast<CommandNode&>(lookup(name)); return dynamic_cast<CommandNode&>(lookup(name));
} }
prefix_ senf::console::DirectoryNode::DirectoryNode(std::string const & name, bool managed) prefix_ senf::console::DirectoryNode &
: GenericNode(name, managed) senf::console::DirectoryNode::mkdir(std::string const & name)
{
return static_cast<DirectoryNode &>(
add(std::auto_ptr<GenericNode>(new DirectoryNode(name))));
}
prefix_ senf::console::DirectoryNode::ChildrenRange senf::console::DirectoryNode::children()
const
{
return boost::make_iterator_range(children_.begin(), children_.end());
}
prefix_ senf::console::DirectoryNode::DirectoryNode(std::string const & name)
: GenericNode(name)
{} {}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::console::CommandNode // senf::console::CommandNode
prefix_ senf::console::CommandNode::CommandNode(std::string const & name, bool managed) prefix_ senf::console::CommandNode::CommandNode(std::string const & name)
: GenericNode(name, managed) : GenericNode(name)
{} {}
///////////////////////////////cci.e/////////////////////////////////////// ///////////////////////////////cci.e///////////////////////////////////////
......
...@@ -28,9 +28,11 @@ ...@@ -28,9 +28,11 @@
// Custom includes // Custom includes
#include <map> #include <map>
#include <boost/intrusive_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include "../Utils/intrusive_refcount.hh" #include <boost/range/iterator_range.hpp>
#include "../Utils/Exception.hh" #include "../Utils/Exception.hh"
//#include "Node.mpp" //#include "Node.mpp"
...@@ -45,59 +47,77 @@ namespace console { ...@@ -45,59 +47,77 @@ namespace console {
/** \brief /** \brief
*/ */
class GenericNode class GenericNode
: public intrusive_refcount_t<GenericNode> : public boost::enable_shared_from_this<GenericNode>
{ {
public: public:
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Types // Types
typedef boost::intrusive_ptr<GenericNode> ptr; typedef boost::shared_ptr<GenericNode> ptr;
typedef boost::weak_ptr<GenericNode> weak_ptr;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
virtual ~GenericNode();
std::string const & name() const; std::string const & name() const;
DirectoryNode & parent() const; boost::shared_ptr<DirectoryNode> parent() const;
bool managed() const; bool managed() const;
std::string path() const;
protected: protected:
explicit GenericNode(std::string const & name, bool managed = false); explicit GenericNode(std::string const & name);
void name(std::string const & name); void name(std::string const & name);
static void name(GenericNode & node, std::string const & name); static void name(GenericNode & node, std::string const & name);
void parent(DirectoryNode * parent); void parent(DirectoryNode * parent);
private: private:
bool release();
std::string name_; std::string name_;
bool managed_;
DirectoryNode * parent_; DirectoryNode * parent_;
friend class intrusive_refcount_base; friend class intrusive_refcount_base;
friend class DirectoryNode;
}; };
/** \brief /** \brief
*/ */
class DirectoryNode : public GenericNode class DirectoryNode : public GenericNode
{ {
typedef std::map<std::string, GenericNode::ptr> ChildMap;
public: public:
typedef boost::intrusive_ptr<DirectoryNode> ptr; ///////////////////////////////////////////////////////////////////////////
// Types
typedef boost::shared_ptr<DirectoryNode> ptr;
typedef boost::weak_ptr<DirectoryNode> weak_ptr;
typedef boost::iterator_range<ChildMap::const_iterator> ChildrenRange;
typedef ChildMap::const_iterator child_iterator;
///////////////////////////////////////////////////////////////////////////
void add(std::auto_ptr<GenericNode> node, bool uniquify = true); GenericNode & add(std::auto_ptr<GenericNode> node, bool uniquify = true);
void add(GenericNode & node, bool uniquify = true);
DirectoryNode & operator[](std::string const & name) const; DirectoryNode & operator[](std::string const & name) const;
CommandNode & operator()(std::string const & name) const; CommandNode & operator()(std::string const & name) const;
DirectoryNode & mkdir(std::string const & name);
ChildrenRange children() const;
protected: protected:
explicit DirectoryNode(std::string const & name, bool managed = false); explicit DirectoryNode(std::string const & name);
private: private:
void add(GenericNode::ptr node, bool uniquify); void add(GenericNode::ptr node, bool uniquify);
GenericNode & lookup(std::string const & name) const; GenericNode & lookup(std::string const & name) const;
typedef std::map<std::string, GenericNode::ptr> ChildMap;
ChildMap children_; ChildMap children_;
friend DirectoryNode & root();
}; };
struct DuplicateNodeNameException : public senf::Exception struct DuplicateNodeNameException : public senf::Exception
...@@ -111,15 +131,23 @@ namespace console { ...@@ -111,15 +131,23 @@ namespace console {
class CommandNode : public GenericNode class CommandNode : public GenericNode
{ {
public: public:
typedef boost::intrusive_ptr<CommandNode> ptr; ///////////////////////////////////////////////////////////////////////////
// Types
typedef boost::shared_ptr<CommandNode> ptr;
typedef boost::weak_ptr<CommandNode> weak_ptr;
///////////////////////////////////////////////////////////////////////////
protected: protected:
explicit CommandNode(std::string const & name, bool managed = false); explicit CommandNode(std::string const & name);
private: private:
}; };
DirectoryNode & root();
}} }}
///////////////////////////////hh.e//////////////////////////////////////// ///////////////////////////////hh.e////////////////////////////////////////
......
...@@ -126,7 +126,7 @@ namespace detail { ...@@ -126,7 +126,7 @@ namespace detail {
{ {
boost::spirit::rule<Scanner> command, path, argument, word, string, hexstring, token, boost::spirit::rule<Scanner> command, path, argument, word, string, hexstring, token,
punctuation, hexbyte, balanced_tokens, simple_argument, complex_argument, builtin, punctuation, hexbyte, balanced_tokens, simple_argument, complex_argument, builtin,
skip, commands, block, statement; skip, commands, block, statement, relpath, abspath;
boost::spirit::chset<> special_p, punctuation_p, space_p, invalid_p, word_p; boost::spirit::chset<> special_p, punctuation_p, space_p, invalid_p, word_p;
boost::spirit::distinct_parser<> keyword_p; boost::spirit::distinct_parser<> keyword_p;
...@@ -157,13 +157,50 @@ namespace detail { ...@@ -157,13 +157,50 @@ namespace detail {
using namespace boost::spirit; using namespace boost::spirit;
typedef ParseDispatcher PD; typedef ParseDispatcher PD;
///////////////////////////////////////////////////////////////////
// Spirit grammar
//
// Syntax summary:
// This is EBNF with some minor tweaks to accommodate C++ syntax
//
// * and + precede their argument
// >> is followed by
// ! optional
// a % b match any number of a's separated by b
// a - b match a but not b
//
// Beside this, we use some special parsers (ch_p, eps_p, confix_p, lex_escape_ch_p,
// keyword_p, comment_p) and directives (lexeme_d), however, the parser should be
// quite readable.
//
// ch_p match character
// eps_p always matches nothing (to attach unconditional actions)
// confix_p(a,b,c) match b, preceded by a and terminated by c. Used to parse
// string literals and comments
// lex_escape_ch_p match a lex style escape char. This is like a C++ style
// literal string escape char, however \x will be replaced by 'x'
// for any char 'x' if it has no special meaning.
// keyword_p match a delimited keyword
// comment_p(a,b) match comment starting with a and terminated with b. b
// defaults to end-of-line
//
// lexeme_d don't skip whitespace (as defined by the skip parser)
//
// Aligned to the right at column 50 are semantic actions.
//
// For clarity, I have used 'ch_p' explicitly throughout even though it is auxiliary
// in most cases.
//
// More info is in the Boost.Spirit documentation
commands commands
= * command = * command
; ;
command command
= builtin = builtin >> (ch_p(';') | end_p)
| path >> ( block | statement ) | path >> ( block | statement )
| ch_p(';') // Ignore empty commands
; ;
builtin builtin
...@@ -232,12 +269,22 @@ namespace detail { ...@@ -232,12 +269,22 @@ namespace detail {
path // Returns value in context.path path // Returns value in context.path
= eps_p [ clear_a(self.context.path) ] = eps_p [ clear_a(self.context.path) ]
>> ( ! ch_p('/') [ push_back_a(self.context.path, "") ] ) >> relpath | abspath
>> ( word [ push_back_a(self.context.path) ] ;
relpath
= ( word [ push_back_a(self.context.path) ]
% ch_p('/') ) % ch_p('/') )
>> ( ! ch_p('/') [ push_back_a(self.context.path,"") ] ) >> ( ! ch_p('/') [ push_back_a(self.context.path,"") ] )
; ;
abspath
= ch_p('/') [ push_back_a(self.context.path, "") ]
>> ! ( ( word [ push_back_a(self.context.path) ]
% ch_p('/') )
>> ( ! ch_p('/') [ push_back_a(self.context.path,"") ] ) )
;
balanced_tokens balanced_tokens
= ch_p('(') [ self.dispatch(&PD::pushPunctuation, "(") ] = ch_p('(') [ self.dispatch(&PD::pushPunctuation, "(") ]
>> * token >> * token
...@@ -269,6 +316,13 @@ namespace detail { ...@@ -269,6 +316,13 @@ namespace detail {
= space_p | comment_p('#') = space_p | comment_p('#')
; ;
///////////////////////////////////////////////////////////////////
start_parsers(
commands, // CommandParser
skip // SkipParser
);
BOOST_SPIRIT_DEBUG_TRACE_RULE(command,1); BOOST_SPIRIT_DEBUG_TRACE_RULE(command,1);
BOOST_SPIRIT_DEBUG_TRACE_RULE(path,1); BOOST_SPIRIT_DEBUG_TRACE_RULE(path,1);
BOOST_SPIRIT_DEBUG_TRACE_RULE(argument,1); BOOST_SPIRIT_DEBUG_TRACE_RULE(argument,1);
...@@ -282,12 +336,11 @@ namespace detail { ...@@ -282,12 +336,11 @@ namespace detail {
BOOST_SPIRIT_DEBUG_TRACE_RULE(simple_argument,1); BOOST_SPIRIT_DEBUG_TRACE_RULE(simple_argument,1);
BOOST_SPIRIT_DEBUG_TRACE_RULE(complex_argument,1); BOOST_SPIRIT_DEBUG_TRACE_RULE(complex_argument,1);
BOOST_SPIRIT_DEBUG_TRACE_RULE(builtin,1); BOOST_SPIRIT_DEBUG_TRACE_RULE(builtin,1);
BOOST_SPIRIT_DEBUG_TRACE_RULE(commands,1);
start_parsers( BOOST_SPIRIT_DEBUG_TRACE_RULE(block,1);
commands, // CommandParser BOOST_SPIRIT_DEBUG_TRACE_RULE(statement,1);
skip // SkipParser BOOST_SPIRIT_DEBUG_TRACE_RULE(relpath,1);
); BOOST_SPIRIT_DEBUG_TRACE_RULE(abspath,1);
} }
}; };
}; };
......
...@@ -104,7 +104,7 @@ prefix_ void senf::console::Server::removeClient(Client & client) ...@@ -104,7 +104,7 @@ prefix_ void senf::console::Server::removeClient(Client & client)
prefix_ senf::console::Client::Client(ClientHandle handle, std::string const & name) prefix_ senf::console::Client::Client(ClientHandle handle, std::string const & name)
: handle_ (handle), name_ (name), out_(::dup(handle.fd())) : handle_ (handle), name_ (name), out_(::dup(handle.fd()))
{ {
out_ << name_ << "# " << std::flush; showPrompt();
ReadHelper<ClientHandle>::dispatch( handle_, 16384u, ReadUntil("\n"), ReadHelper<ClientHandle>::dispatch( handle_, 16384u, ReadUntil("\n"),
senf::membind(&Client::clientData, this) ); senf::membind(&Client::clientData, this) );
} }
...@@ -145,11 +145,16 @@ prefix_ void senf::console::Client::clientData(ReadHelper<ClientHandle>::ptr hel ...@@ -145,11 +145,16 @@ prefix_ void senf::console::Client::clientData(ReadHelper<ClientHandle>::ptr hel
return; return;
} }
out_ << name_ << "# " << std::flush; showPrompt();
ReadHelper<ClientHandle>::dispatch( handle_, 16384u, ReadUntil("\n"), ReadHelper<ClientHandle>::dispatch( handle_, 16384u, ReadUntil("\n"),
senf::membind(&Client::clientData, this) ); senf::membind(&Client::clientData, this) );
} }
prefix_ void senf::console::Client::showPrompt()
{
out_ << name_ << ":" << executor_.cwd().path() << "# " << std::flush;
}
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_ #undef prefix_
//#include "Server.mpp" //#include "Server.mpp"
......
...@@ -113,6 +113,7 @@ namespace console { ...@@ -113,6 +113,7 @@ namespace console {
Client(ClientHandle handle, std::string const & name); Client(ClientHandle handle, std::string const & name);
void clientData(ReadHelper<ClientHandle>::ptr helper); void clientData(ReadHelper<ClientHandle>::ptr helper);
void showPrompt();
ClientHandle handle_; ClientHandle handle_;
std::string tail_; std::string tail_;
......
...@@ -40,6 +40,9 @@ int main(int, char const **) ...@@ -40,6 +40,9 @@ int main(int, char const **)
{ {
senf::log::ConsoleTarget::instance().route< senf::SenfLog, senf::log::NOTICE >(); senf::log::ConsoleTarget::instance().route< senf::SenfLog, senf::log::NOTICE >();
senf::console::root().mkdir("network").mkdir("eth0");
senf::console::root().mkdir("server");
senf::console::Server::start( senf::INet4SocketAddress("127.0.0.1:23232") ) senf::console::Server::start( senf::INet4SocketAddress("127.0.0.1:23232") )
.name("testServer"); .name("testServer");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment