diff --git a/Msh.pro b/Msh.pro index fb8889c..62c9cfd 100644 --- a/Msh.pro +++ b/Msh.pro @@ -6,9 +6,11 @@ CONFIG -= qt SOURCES += main.cpp \ command.cpp \ commands.cpp \ - cmds.cpp + cmds.cpp \ + console.cpp HEADERS += \ command.h \ commands.h \ - cmds.h + cmds.h \ + console.h diff --git a/cmds.cpp b/cmds.cpp index 57b3937..d79d8d4 100644 --- a/cmds.cpp +++ b/cmds.cpp @@ -21,9 +21,7 @@ int Cmds::exitExecute(const vector*){ } int Cmds::helpExecute(const vector*){ - int i; - cout << "Claudio Maggioni's msh\n" << endl - << "Type program names and arguments, and hit enter.\n" << endl; + cout << "Msh info" << endl; return 1; } diff --git a/commands.cpp b/commands.cpp index d16293c..bc9a8b9 100644 --- a/commands.cpp +++ b/commands.cpp @@ -17,7 +17,7 @@ void Commands::add(Command* cmd){ commands.push_back(cmd); } -int Commands::howMany(){ +size_t Commands::howMany(){ return commands.size(); } diff --git a/commands.h b/commands.h index 15ed0d0..a6a8080 100644 --- a/commands.h +++ b/commands.h @@ -15,7 +15,7 @@ class Commands public: Commands(); void add(Command*); - int howMany(); + size_t howMany(); int launch(const vector* args); }; diff --git a/console.cpp b/console.cpp new file mode 100644 index 0000000..976cae0 --- /dev/null +++ b/console.cpp @@ -0,0 +1,112 @@ +#include "console.h" + +Commands Console::cmds; + +int Console::launch(vector* args) +{ + pid_t pid; + int status; + + pid = fork(); + if (pid == 0) { + vector argv(args->size() + 1); + size_t i; + for (i = 0; i != args->size()-1; ++i) + { + argv[i] = &(args->operator[](i)[0]); + } + argv[i] = NULL; + if(execvp(argv[0], argv.data()) == -1) { + cerr << "msh: command " << args->operator [](0) << " not found\n"; + } + exit(EXIT_FAILURE); + } + else if (pid < 0) { + // Error forking + cerr << "msh: error forking\n"; + } + else { + // Parent process + do { + waitpid(pid, &status, WUNTRACED); + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + } + return 1; +} + +int Console::execute(vector* args) +{ + if (args->operator [](0) == "\0") { + // An empty command was entered. + return 1; + } + int a; + try { + a=cmds.launch(args); + } + catch (CommandNotFoundException){ + return launch(args); + } + return a; +} + + + +bool undoingLine=false; + +void Console::mshEofHandler(int){ + undoingLine = true; +} + +string* Console::read_line() +{ + string* buffer = new string(); + struct sigaction *sa = new struct sigaction(); + sa->sa_handler = mshEofHandler; + sa->sa_flags = 0; // not SA_RESTART!; + sigaction(SIGINT, sa, NULL); + getline(cin,*buffer); // get command + cin.clear(); // clear flags + + if(undoingLine){ + undoingLine=false; + throw IsUndoingLineException(); + } + + return buffer; +} + +vector* Console::split_line(string* line) +{ + vector* tokens = new vector(); + string ln = *line; + istringstream is(ln); + int i; + for(i=0; getline(is, ln, ' '); i++){ + tokens->push_back(ln); + } + tokens->push_back("\0"); + 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); +} diff --git a/console.h b/console.h new file mode 100644 index 0000000..09e00be --- /dev/null +++ b/console.h @@ -0,0 +1,35 @@ +#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 3766267..b6cc474 100644 --- a/main.cpp +++ b/main.cpp @@ -2,143 +2,17 @@ * Edit of lsh from https://github.com/brenns10/msh.git rewritten in C++ * by Claudio Maggiobi */ - -#include -#include +#include "console.h" #include -#include -#include -#include -#include -#include -#include -#include -#include using namespace std; -Commands cmds; - -int msh_launch(vector* args) -{ - pid_t pid; - int status; - - pid = fork(); - if (pid == 0) { - vector argv(args->size() + 1); - size_t i; - for (i = 0; i != args->size()-1; ++i) - { - argv[i] = &(args->operator[](i)[0]); - } - argv[i] = NULL; - if(execvp(argv[0], argv.data()) == -1) { - cerr << "msh: command " << args->operator [](0) << " not found\n"; - } - exit(EXIT_FAILURE); - } - else if (pid < 0) { - // Error forking - cerr << "msh: error forking\n"; - } - else { - // Parent process - - do { - waitpid(pid, &status, WUNTRACED); - } while (!WIFEXITED(status) && !WIFSIGNALED(status)); - } - return 1; -} - -int msh_execute(vector* args) -{ - if (args->operator [](0) == "\0") { - // An empty command was entered. - return 1; - } - int a; - try { - a=cmds.launch(args); - } - catch (CommandNotFoundException){ - return msh_launch(args); - } - return a; -} - -class IsUndoingLineException {}; - -bool undoingLine=false; - -void mshEofHandler(int){ - undoingLine = true; -} - -string* msh_read_line() -{ - string* buffer = new string(); - struct sigaction *sa = new struct sigaction(); - sa->sa_handler = mshEofHandler; - sa->sa_flags = 0; // not SA_RESTART!; - sigaction(SIGINT, sa, NULL); - - getline(cin,*buffer); // get command - cin.clear(); // clear flags - - if(undoingLine){ - undoingLine=false; - throw IsUndoingLineException(); - } - - return buffer; -} - -vector* msh_split_line(string* line) -{ - vector* tokens = new vector(); - string ln = *line; - istringstream is(ln); - int i; - for(i=0; getline(is, ln, ' '); i++){ - tokens->push_back(ln); - } - tokens->push_back("\0"); - return tokens; -} - -inline void msh_loop(void) -{ - string* line; - vector* args; - int status; - - do { - bool readSuccess; - do{ - cout << "MSH$ "; - try{ - line = msh_read_line(); - readSuccess = true; - } - catch (IsUndoingLineException){ - cout << "\n"; - readSuccess = false; - } - }while(!readSuccess); - args = msh_split_line(line); - status = msh_execute(args); - - } while (status); -} - int main(int argc, char **argv) { // Load config files, if any. // Run command loop - msh_loop(); + Console::loop(); // Perform any shutdown/cleanup.