#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); }