113 lines
2.2 KiB
C++
113 lines
2.2 KiB
C++
|
#include "console.h"
|
||
|
|
||
|
Commands Console::cmds;
|
||
|
|
||
|
int Console::launch(vector<string>* args)
|
||
|
{
|
||
|
pid_t pid;
|
||
|
int status;
|
||
|
|
||
|
pid = fork();
|
||
|
if (pid == 0) {
|
||
|
vector<char *> 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<string>* 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<string>* Console::split_line(string* line)
|
||
|
{
|
||
|
vector<string>* tokens = new vector<string>();
|
||
|
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<string>* 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);
|
||
|
}
|