diff --git a/Msh.pro b/Msh.pro index 62c9cfd..765a61d 100644 --- a/Msh.pro +++ b/Msh.pro @@ -7,10 +7,10 @@ SOURCES += main.cpp \ command.cpp \ commands.cpp \ cmds.cpp \ - console.cpp + shell.cpp HEADERS += \ command.h \ commands.h \ - cmds.h \ - console.h + shell.h \ + cmds.h diff --git a/cmds.cpp b/cmds.cpp index d79d8d4..b39d5a5 100644 --- a/cmds.cpp +++ b/cmds.cpp @@ -7,21 +7,21 @@ using namespace std; int Cmds::cdExecute(const vector* args){ if (args->operator[](1) == "\0") { - cerr << "msh: expected argument to \"cd\"\n"; + cerr << "expected argument to \"cd\"\n"; } else { if (chdir(args->operator[](1).c_str()) != 0) { - cerr << "msh"; + cerr << "error"; } } return 1; } int Cmds::exitExecute(const vector*){ - std::exit(0); + return 0; } int Cmds::helpExecute(const vector*){ - cout << "Msh info" << endl; + cout << " info" << endl; return 1; } diff --git a/cmds.h b/cmds.h index f170d82..e0f8925 100644 --- a/cmds.h +++ b/cmds.h @@ -1,9 +1,6 @@ -/** - builtin commands -*/ - #ifndef CMDS_H #define CMDS_H + #include #include #include diff --git a/commands.cpp b/commands.cpp index bc9a8b9..76b29f9 100644 --- a/commands.cpp +++ b/commands.cpp @@ -6,11 +6,6 @@ Commands::Commands() { if(created) throw CommandsAlreadyCreatedException(); created=true; - - //add builtin commands - add(new Command("cd", &cdExecute)); - add(new Command("exit", &exitExecute)); - add(new Command("help", &helpExecute)); } void Commands::add(Command* cmd){ @@ -22,7 +17,7 @@ size_t Commands::howMany(){ } int Commands::launch(const vector* args){ - for(int i=0; igetName())==args->operator [](0)){ return commands[i]->execute(args); } @@ -32,5 +27,4 @@ int Commands::launch(const vector* args){ bool Commands::created = false; -//builtin commands diff --git a/console.h b/console.h deleted file mode 100644 index 09e00be..0000000 --- a/console.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef CONSOLE_H -#define CONSOLE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using std::cin; -using std::cout; -using std::cerr; -using std::string; -using std::vector; -using std::istringstream; - - -namespace Console{ - extern Commands cmds; - - class IsUndoingLineException {}; - - int launch(vector* args); - int execute(vector* args); - void mshEofHandler(int); - string* read_line(); - vector* split_line(string* line); - void loop(); -} -#endif // CONSOLE_H diff --git a/main.cpp b/main.cpp index 21002e1..e976aae 100644 --- a/main.cpp +++ b/main.cpp @@ -1,17 +1,27 @@ -#include "console.h" #include +#include +#include "shell.h" +#include "command.h" +#include "cmds.h" using namespace std; +using namespace Cmds; + +static void setup(Shell *); int main(int argc, char **argv) { - // Load config files, if any. + string c = "msh-console-test"; + string ps = "[msh-console-test]:"; + Shell mshConsoleTest(c, ps, &setup); - // Run command loop - - Console::loop(); - - // Perform any shutdown/cleanup. - - return EXIT_SUCCESS; + //add builtin commands + mshConsoleTest.addCmd(new Command("cd", &cdExecute)); + mshConsoleTest.addCmd(new Command("exit", &exitExecute)); + mshConsoleTest.addCmd(new Command("help", &helpExecute)); + mshConsoleTest.loop(); + return EXIT_SUCCESS; } +void setup(Shell *){ + cout << "Now entering in test shell...\n" << endl; +} diff --git a/console.cpp b/shell.cpp similarity index 61% rename from console.cpp rename to shell.cpp index 976cae0..712b56c 100644 --- a/console.cpp +++ b/shell.cpp @@ -1,8 +1,59 @@ -#include "console.h" +#include "shell.h" -Commands Console::cmds; +string Shell::getPs() const +{ + return ps; +} -int Console::launch(vector* args) +void Shell::setPs(const string &value) +{ + ps = value; +} + +string Shell::getName() const +{ + return name; +} + +void Shell::setName(const string &value) +{ + name = value; +} + +Shell::Shell( string n, string ps,void (*s)(Shell*)) : cmds() +{ + shellSetup = s; + name = n; + this->ps = ps; +} + +void Shell::loop(){ + //launch setup + if(shellSetup!=0) (*shellSetup)(this); + + //launch loop + string* line; + vector* args; + int status; + do { + bool readSuccess; + do{ + cout << ps << " "; + try{ + line = read_line(); + readSuccess = true; + } + catch (IsUndoingLineException){ + cout << "\n"; + readSuccess = false; + } + }while(!readSuccess); + args = split_line(line); + status = execute(args); + } while (status); +} + +int Shell::launch(vector* args) { pid_t pid; int status; @@ -17,13 +68,13 @@ int Console::launch(vector* args) } argv[i] = NULL; if(execvp(argv[0], argv.data()) == -1) { - cerr << "msh: command " << args->operator [](0) << " not found\n"; + cerr << name <<": command " << args->operator [](0) << " not found\n"; } exit(EXIT_FAILURE); } else if (pid < 0) { // Error forking - cerr << "msh: error forking\n"; + cerr << name <<": error forking\n"; } else { // Parent process @@ -34,7 +85,7 @@ int Console::launch(vector* args) return 1; } -int Console::execute(vector* args) +int Shell::execute(vector* args) { if (args->operator [](0) == "\0") { // An empty command was entered. @@ -45,26 +96,27 @@ int Console::execute(vector* args) a=cmds.launch(args); } catch (CommandNotFoundException){ - return launch(args); + return launch(args); } return a; } - - -bool undoingLine=false; - -void Console::mshEofHandler(int){ +void Shell::EofHandler(int){ undoingLine = true; } -string* Console::read_line() -{ - string* buffer = new string(); +void setEofHandler(void (*funcptr)(int)){ struct sigaction *sa = new struct sigaction(); - sa->sa_handler = mshEofHandler; + sa->sa_handler = funcptr; sa->sa_flags = 0; // not SA_RESTART!; sigaction(SIGINT, sa, NULL); + delete sa; +} + +string* Shell::read_line() +{ + string* buffer = new string(); + setEofHandler(EofHandler); getline(cin,*buffer); // get command cin.clear(); // clear flags @@ -72,11 +124,10 @@ string* Console::read_line() undoingLine=false; throw IsUndoingLineException(); } - return buffer; } -vector* Console::split_line(string* line) +vector* Shell::split_line(string* line) { vector* tokens = new vector(); string ln = *line; @@ -89,24 +140,12 @@ vector* Console::split_line(string* line) return tokens; } -void Console::loop(){ - string* line; - vector* args; - int status; - do { - bool readSuccess; - do{ - cout << "MSH$ "; - try{ - line = read_line(); - readSuccess = true; - } - catch (IsUndoingLineException){ - cout << "\n"; - readSuccess = false; - } - }while(!readSuccess); - args = split_line(line); - status = execute(args); - } while (status); +bool Shell::undoingLine = false; + +void Shell::addCmd(Command* cmd){ + cmds.add(cmd); +} + +size_t Shell::howManyCmds(){ + return cmds.howMany(); } diff --git a/shell.h b/shell.h new file mode 100644 index 0000000..f8d5168 --- /dev/null +++ b/shell.h @@ -0,0 +1,50 @@ +#ifndef SHELL_H +#define SHELL_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using std::string; +using std::cin; +using std::cout; +using std::cerr; +using std::string; +using std::vector; +using std::istringstream; +using std::nullptr_t; + +class Shell +{ + static bool undoingLine; + Commands cmds; + string ps; + string name; + void (*shellSetup)(Shell *); + + class IsUndoingLineException {}; + + int launch(vector* args); + int execute(vector* args); + static void EofHandler(int); + string* read_line(); + vector* split_line(string* line); +public: + Shell( string n="msh", string ps="MSH$",void (*s)(Shell*)=0); + string getPs() const; + void setPs(const string &value); + string getName() const; + void setName(const string &value); + void loop(); + + //for in-shell commands + void addCmd(Command *cmd); + size_t howManyCmds(); +}; + +#endif // SHELL_H