2016-03-16 20:15:24 +00:00
|
|
|
#include "shell.h"
|
2016-03-18 17:48:16 +00:00
|
|
|
namespace mshconsole {
|
|
|
|
string Shell::getPs() const
|
|
|
|
{
|
|
|
|
return ps;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void Shell::setPs(const string &value)
|
|
|
|
{
|
|
|
|
ps = value;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
string Shell::getName() const
|
|
|
|
{
|
|
|
|
return name;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void Shell::setName(const string &value)
|
|
|
|
{
|
|
|
|
name = value;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
Shell::Shell( string n, string ps,void (*s)(Shell*), void (*pss)(Shell*)) : cmds(this)
|
|
|
|
{
|
|
|
|
shellSetup = s;
|
|
|
|
name = n;
|
|
|
|
this->ps = ps;
|
|
|
|
shellPostSetup = pss;
|
|
|
|
notLoop = false;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-04-02 14:28:03 +00:00
|
|
|
int Shell::launch(){
|
2016-03-18 17:48:16 +00:00
|
|
|
|
2016-04-02 14:28:03 +00:00
|
|
|
//launch setup
|
|
|
|
if(notLoop) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if(shellSetup!=0) {
|
2016-03-18 17:48:16 +00:00
|
|
|
notLoop = true;
|
|
|
|
(*shellSetup)(this);
|
|
|
|
notLoop = false;
|
2016-04-02 14:28:03 +00:00
|
|
|
}
|
2016-03-18 17:48:16 +00:00
|
|
|
|
2016-04-02 14:28:03 +00:00
|
|
|
//launch loop
|
|
|
|
string* line;
|
2016-04-16 17:21:39 +00:00
|
|
|
struct Params p;
|
2016-04-02 14:28:03 +00:00
|
|
|
int exitCode;
|
|
|
|
try{
|
2016-03-18 17:48:16 +00:00
|
|
|
do {
|
|
|
|
bool readSuccess;
|
|
|
|
do{
|
|
|
|
cout << ps << " ";
|
|
|
|
try{
|
|
|
|
line = read_line();
|
|
|
|
readSuccess = true;
|
|
|
|
}
|
|
|
|
catch (IsUndoingLineException){
|
|
|
|
cout << "\n";
|
|
|
|
readSuccess = false;
|
|
|
|
}
|
|
|
|
}while(!readSuccess);
|
2016-04-16 17:21:39 +00:00
|
|
|
p = split_line(line);
|
|
|
|
executeCmd(p);
|
|
|
|
} while (1);
|
2016-04-02 14:28:03 +00:00
|
|
|
} catch(CommandExecutor::ExitException c) {
|
|
|
|
exitCode=c.getCode();
|
|
|
|
}
|
2016-03-18 17:48:16 +00:00
|
|
|
|
2016-04-02 14:28:03 +00:00
|
|
|
//launch postSetup
|
|
|
|
if(shellPostSetup!=0) {
|
2016-03-18 17:48:16 +00:00
|
|
|
shellPostSetup(this);
|
2016-04-02 14:28:03 +00:00
|
|
|
}
|
|
|
|
return exitCode;
|
2016-03-18 17:48:16 +00:00
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-04-16 17:21:39 +00:00
|
|
|
int Shell::launchCmd(const struct Params& p)
|
2016-03-18 17:48:16 +00:00
|
|
|
{
|
|
|
|
using std::exit;
|
|
|
|
int status;
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
pid_t pid = fork();
|
|
|
|
if (pid == 0) {
|
|
|
|
//child process
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
//execute threadCommand
|
|
|
|
int a;
|
|
|
|
try {
|
2016-04-16 17:21:39 +00:00
|
|
|
a=cmds.launch(p, true);
|
2016-03-16 20:15:24 +00:00
|
|
|
}
|
2016-03-18 17:48:16 +00:00
|
|
|
catch (CommandNotFoundException){
|
|
|
|
//execute bash command or program
|
2016-04-16 17:21:39 +00:00
|
|
|
if((a=execvp(p.argv[0], p.argv)) == -1) {
|
|
|
|
cerr << name <<": command " << p.argv[0] << " not found\n";
|
2016-03-18 17:48:16 +00:00
|
|
|
}
|
|
|
|
exit(EXIT_FAILURE);
|
2016-03-16 20:15:24 +00:00
|
|
|
}
|
2016-03-18 17:48:16 +00:00
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
else if (pid < 0) {
|
|
|
|
// Error forking
|
|
|
|
cerr << name <<": error forking the process\n";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Parent process
|
|
|
|
do {
|
|
|
|
//wait until child finished
|
|
|
|
waitpid(pid, &status, WUNTRACED);
|
|
|
|
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
2016-03-16 20:15:24 +00:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2016-03-18 17:48:16 +00:00
|
|
|
|
2016-04-16 17:21:39 +00:00
|
|
|
int Shell::executeCmd(const struct Params& p)
|
2016-03-18 17:48:16 +00:00
|
|
|
{
|
2016-04-16 17:21:39 +00:00
|
|
|
if (!p.argc) { //empty line
|
2016-03-18 17:48:16 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
int ret;
|
|
|
|
try {
|
2016-04-16 17:21:39 +00:00
|
|
|
ret = cmds.launch(p, false);
|
2016-03-18 17:48:16 +00:00
|
|
|
}
|
|
|
|
catch(CommandNotFoundException) {
|
2016-04-16 17:21:39 +00:00
|
|
|
ret = launchCmd(p);
|
2016-03-18 17:48:16 +00:00
|
|
|
}
|
|
|
|
return ret;
|
2016-03-16 20:15:24 +00:00
|
|
|
}
|
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
inline int Shell::executeCmd(const std::string &args){
|
|
|
|
return executeCmd(split_line(&args));
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void Shell::EofHandler(int){
|
|
|
|
undoingLine = true;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void Shell::setShellSetup(void (*s)(Shell *)){
|
|
|
|
shellSetup=s;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void (*Shell::getShellSetup())(Shell*) {
|
|
|
|
return shellSetup;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void Shell::setShellPostSetup(void (*s)(Shell *)){
|
|
|
|
shellPostSetup=s;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void (*Shell::getShellPostSetup())(Shell*) {
|
|
|
|
return shellPostSetup;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void setEofHandler(void (*funcptr)(int)){
|
|
|
|
struct sigaction *sa = new struct sigaction();
|
|
|
|
sa->sa_handler = funcptr;
|
|
|
|
sa->sa_flags = 0; // not SA_RESTART!;
|
|
|
|
sigaction(SIGINT, sa, NULL);
|
|
|
|
delete sa;
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
string* Shell::read_line()
|
|
|
|
{
|
|
|
|
string* buffer = new string();
|
|
|
|
setEofHandler(EofHandler);
|
|
|
|
getline(cin,*buffer); // get command
|
|
|
|
cin.clear(); // clear flags
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
if(undoingLine){
|
|
|
|
undoingLine=false;
|
|
|
|
throw IsUndoingLineException();
|
|
|
|
}
|
|
|
|
return buffer;
|
2016-03-16 20:15:24 +00:00
|
|
|
}
|
|
|
|
|
2016-04-16 17:21:39 +00:00
|
|
|
struct Params Shell::split_line(const string* line){
|
|
|
|
struct Params p;
|
|
|
|
stringToArgcArgv(*line, &(p.argc), &(p.argv));
|
|
|
|
return p;
|
2016-03-18 17:48:16 +00:00
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
bool Shell::undoingLine = false;
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
void Shell::addCmd(Command* cmd, bool isthread){
|
|
|
|
cmds.add(cmd, isthread);
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
|
2016-03-18 17:48:16 +00:00
|
|
|
size_t Shell::howManyCmds() const{
|
|
|
|
return cmds.howMany();
|
|
|
|
}
|
2016-03-16 20:15:24 +00:00
|
|
|
}
|