/** * Edit of lsh from https://github.com/brenns10/msh.git rewritten in C++ * by Claudio Maggiobi */ #include #include #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(); // Perform any shutdown/cleanup. return EXIT_SUCCESS; }