Command functions have now a CommandExecutor* arg, parent of Shell class. Added possibility to make a threadCommand (a built-in command that runs in his thread).
This commit is contained in:
parent
e9e95a519d
commit
13db9109d9
10 changed files with 127 additions and 74 deletions
6
Msh.pro
6
Msh.pro
|
@ -7,9 +7,11 @@ SOURCES += main.cpp \
|
|||
command.cpp \
|
||||
commands.cpp \
|
||||
cmds.cpp \
|
||||
shell.cpp
|
||||
shell.cpp \
|
||||
commandexecutor.cpp
|
||||
|
||||
HEADERS += \
|
||||
command.h \
|
||||
shell.h \
|
||||
cmds.h
|
||||
cmds.h \
|
||||
commandexecutor.h
|
||||
|
|
9
cmds.cpp
9
cmds.cpp
|
@ -3,9 +3,10 @@
|
|||
*/
|
||||
|
||||
#include "cmds.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int Cmds::cdExecute(const vector<string>* args){
|
||||
int Cmds::cdExecute(const vector<string>* args, CommandExecutor*){
|
||||
if (args->operator[](1) == "\0") {
|
||||
cerr << "expected argument to \"cd\"\n";
|
||||
} else {
|
||||
|
@ -16,11 +17,11 @@ int Cmds::cdExecute(const vector<string>* args){
|
|||
return 1;
|
||||
}
|
||||
|
||||
int Cmds::exitExecute(const vector<string>*){
|
||||
return 0;
|
||||
int Cmds::exitExecute(const vector<string>*, CommandExecutor*){
|
||||
return 0; //TODO: better exit signal giving
|
||||
}
|
||||
|
||||
int Cmds::helpExecute(const vector<string>*){
|
||||
int Cmds::helpExecute(const vector<string>*, CommandExecutor*){
|
||||
cout << " info" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
|
8
cmds.h
8
cmds.h
|
@ -1,6 +1,6 @@
|
|||
#ifndef CMDS_H
|
||||
#define CMDS_H
|
||||
|
||||
#include "commandexecutor.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
@ -9,9 +9,9 @@ using std::string;
|
|||
using std::vector;
|
||||
|
||||
namespace Cmds {
|
||||
int cdExecute(const vector<string>* args);
|
||||
int exitExecute(const vector<string>*);
|
||||
int helpExecute(const vector<string>*);
|
||||
int cdExecute(const vector<string>* args, CommandExecutor*);
|
||||
int exitExecute(const vector<string>*, CommandExecutor*);
|
||||
int helpExecute(const vector<string>*, CommandExecutor*);
|
||||
}
|
||||
|
||||
#endif // CMDS_H
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#include "shell.h"
|
||||
|
||||
Command::Command(const string& n, int (*funcptr)(const vector<string>* args)) : name(n) , funcCommand(funcptr){
|
||||
Command::Command(const string& n, int (*funcptr)(const vector<string>* args, CommandExecutor*)) : name(n) , funcCommand(funcptr){
|
||||
checkObj();
|
||||
numCom++;
|
||||
}
|
||||
|
||||
int Command::execute(const vector<string>* args){
|
||||
return (*funcCommand)(args);
|
||||
int Command::execute(const vector<string>* args, CommandExecutor* ciao){
|
||||
if(args==nullptr) return -1;
|
||||
return (*funcCommand)(args, ciao);
|
||||
}
|
||||
|
||||
string Command::getName(){
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define COMMAND_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "shell.h"
|
||||
#include "commandexecutor.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -10,15 +12,15 @@ class Command
|
|||
{
|
||||
const string name;
|
||||
static unsigned int numCom;
|
||||
int (*funcCommand)(const vector<string>*);
|
||||
int (*funcCommand)(const vector<string>*,CommandExecutor*);
|
||||
void checkObj();
|
||||
|
||||
public:
|
||||
Command(const string& n, int (*funcptr)(const vector<string>* args));
|
||||
Command(const string& n, int (*funcptr)(const vector<string>* args, CommandExecutor*));
|
||||
Command(const Command&);
|
||||
~Command();
|
||||
string getName();
|
||||
int execute(const vector<string>*);
|
||||
int execute(const vector<string>*, CommandExecutor* ciao);
|
||||
};
|
||||
|
||||
class CommandNameNotValidException{};
|
||||
|
|
6
commandexecutor.cpp
Normal file
6
commandexecutor.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include "commandexecutor.h"
|
||||
|
||||
CommandExecutor::CommandExecutor()
|
||||
{
|
||||
|
||||
}
|
15
commandexecutor.h
Normal file
15
commandexecutor.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef COMMANDEXECUTOR_H
|
||||
#define COMMANDEXECUTOR_H
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class CommandExecutor
|
||||
{
|
||||
public:
|
||||
virtual int executeCmd(std::vector<std::string>* args) = 0;
|
||||
virtual int executeCmd(const std::string& args) = 0;
|
||||
virtual size_t howManyCmds() const = 0;
|
||||
CommandExecutor();
|
||||
};
|
||||
|
||||
#endif // COMMANDEXECUTOR_H
|
18
commands.cpp
18
commands.cpp
|
@ -1,23 +1,25 @@
|
|||
#include "shell.h"
|
||||
|
||||
Shell::Commands::Commands()
|
||||
Shell::Commands::Commands(Shell* s) : commands(), threadCommands()
|
||||
{
|
||||
parent = s;
|
||||
if(created) throw CommandsAlreadyCreatedException();
|
||||
created=true;
|
||||
}
|
||||
|
||||
void Shell::Commands::add(Command* cmd){
|
||||
commands.push_back(cmd);
|
||||
void Shell::Commands::add(Command* cmd, bool isthread){
|
||||
if(!isthread) commands.push_back(cmd);
|
||||
else threadCommands.push_back(cmd);
|
||||
}
|
||||
|
||||
size_t Shell::Commands::howMany(){
|
||||
size_t Shell::Commands::howMany() const{
|
||||
return commands.size();
|
||||
}
|
||||
|
||||
int Shell::Commands::launch(const vector<string>* args){
|
||||
for(unsigned int i=0; i<commands.size(); i++){
|
||||
if((commands[i]->getName())==args->operator [](0)){
|
||||
return commands[i]->execute(args);
|
||||
int Shell::Commands::launch(const vector<string>* args, bool launchThread){
|
||||
for(unsigned int i=0; i<(launchThread ? threadCommands.size() : commands.size()); i++){
|
||||
if((launchThread ? threadCommands[i]->getName() : commands[i]->getName())==args->operator [](0)){
|
||||
return (launchThread ? threadCommands[i]->execute(args, parent) : commands[i]->execute(args, parent));
|
||||
}
|
||||
}
|
||||
throw CommandNotFoundException();
|
||||
|
|
50
shell.cpp
50
shell.cpp
|
@ -20,7 +20,7 @@ void Shell::setName(const string &value)
|
|||
name = value;
|
||||
}
|
||||
|
||||
Shell::Shell( string n, string ps,void (*s)(Shell*)) : cmds()
|
||||
Shell::Shell( string n, string ps,void (*s)(Shell*)) : cmds(this)
|
||||
{
|
||||
shellSetup = s;
|
||||
name = n;
|
||||
|
@ -57,17 +57,26 @@ void Shell::launch(){
|
|||
}
|
||||
}while(!readSuccess);
|
||||
args = split_line(line);
|
||||
status = execute(args);
|
||||
status = executeCmd(args);
|
||||
delete args;
|
||||
} while (status);
|
||||
}
|
||||
|
||||
int Shell::launch(vector<string>* args)
|
||||
int Shell::launchCmd(vector<string>* args)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
pid = fork();
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
//child process
|
||||
|
||||
//execute threadCommand
|
||||
int a;
|
||||
try {
|
||||
a=cmds.launch(args, true);
|
||||
}
|
||||
catch (CommandNotFoundException){
|
||||
//execute bash command or program
|
||||
vector<char *> argv(args->size() + 1);
|
||||
size_t i;
|
||||
for (i = 0; i != args->size()-1; ++i)
|
||||
|
@ -75,38 +84,45 @@ int Shell::launch(vector<string>* args)
|
|||
argv[i] = &(args->operator[](i)[0]);
|
||||
}
|
||||
argv[i] = NULL;
|
||||
if(execvp(argv[0], argv.data()) == -1) {
|
||||
if((a=execvp(argv[0], argv.data())) == -1) {
|
||||
cerr << name <<": command " << args->operator [](0) << " not found\n";
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
else if (pid < 0) {
|
||||
// Error forking
|
||||
cerr << name <<": error forking\n";
|
||||
cerr << name <<": error forking the process\n";
|
||||
}
|
||||
else {
|
||||
// Parent process
|
||||
do {
|
||||
//wait until child finished
|
||||
waitpid(pid, &status, WUNTRACED);
|
||||
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Shell::execute(vector<string>* args)
|
||||
int Shell::executeCmd(vector<string>* args)
|
||||
{
|
||||
if (args->operator [](0) == "\0") {
|
||||
// An empty command was entered.
|
||||
return 1;
|
||||
}
|
||||
int a;
|
||||
int ret;
|
||||
try {
|
||||
a=cmds.launch(args);
|
||||
ret = cmds.launch(args, false);
|
||||
}
|
||||
catch (CommandNotFoundException){
|
||||
return launch(args);
|
||||
catch(CommandNotFoundException) {
|
||||
ret = launchCmd(args);
|
||||
}
|
||||
return a;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int Shell::executeCmd(const std::string &args){
|
||||
return executeCmd(split_line(&args));
|
||||
}
|
||||
|
||||
void Shell::EofHandler(int){
|
||||
|
@ -135,7 +151,7 @@ string* Shell::read_line()
|
|||
return buffer;
|
||||
}
|
||||
|
||||
vector<string>* Shell::split_line(string* line)
|
||||
vector<string>* Shell::split_line(const string* line)
|
||||
{
|
||||
vector<string>* tokens = new vector<string>();
|
||||
string ln = *line;
|
||||
|
@ -150,10 +166,10 @@ vector<string>* Shell::split_line(string* line)
|
|||
|
||||
bool Shell::undoingLine = false;
|
||||
|
||||
void Shell::addCmd(Command* cmd){
|
||||
cmds.add(cmd);
|
||||
void Shell::addCmd(Command* cmd, bool isthread){
|
||||
cmds.add(cmd, isthread);
|
||||
}
|
||||
|
||||
size_t Shell::howManyCmds(){
|
||||
size_t Shell::howManyCmds() const{
|
||||
return cmds.howMany();
|
||||
}
|
||||
|
|
40
shell.h
40
shell.h
|
@ -10,6 +10,8 @@
|
|||
#include <vector>
|
||||
#include <csignal>
|
||||
#include "command.h"
|
||||
//#include "commands.h"
|
||||
#include "commandexecutor.h"
|
||||
using std::string;
|
||||
using std::cin;
|
||||
using std::cout;
|
||||
|
@ -19,20 +21,25 @@ using std::vector;
|
|||
using std::istringstream;
|
||||
using std::nullptr_t;
|
||||
|
||||
class Shell
|
||||
class Shell : public CommandExecutor
|
||||
{
|
||||
class Commands
|
||||
{
|
||||
vector<Command*> commands;
|
||||
static bool created;
|
||||
Commands(Commands&);
|
||||
public:
|
||||
Commands();
|
||||
void add(Command*);
|
||||
size_t howMany();
|
||||
int launch(const vector<string>* args);
|
||||
};
|
||||
Shell* parent;
|
||||
vector<Command*> commands; //commands that work the same thread of the shell
|
||||
vector<Command*> threadCommands; //commands that work on a different thread
|
||||
|
||||
//just one instance of the object
|
||||
static bool created;
|
||||
Commands(const Commands&);
|
||||
Commands operator=(const Commands&);
|
||||
|
||||
public:
|
||||
Commands(Shell*);
|
||||
void add(Command*, bool isthread=false);
|
||||
size_t howMany() const;
|
||||
int launch(const vector<string>* args, bool launchThread=false);
|
||||
};
|
||||
static bool undoingLine;
|
||||
Commands cmds;
|
||||
string ps;
|
||||
|
@ -40,16 +47,15 @@ class Shell
|
|||
void (*shellSetup)(Shell *);
|
||||
bool notLoop;
|
||||
|
||||
int launch(vector<string>* args);
|
||||
int execute(vector<string>* args);
|
||||
int launchCmd(vector<string>* args);
|
||||
static void EofHandler(int);
|
||||
string* read_line();
|
||||
vector<string>* split_line(string* line);
|
||||
vector<string>* split_line(const string* line);
|
||||
|
||||
class IsUndoingLineException {};
|
||||
|
||||
public:
|
||||
Shell( string n="msh", string ps="MSH$",void (*s)(Shell*)=0);
|
||||
Shell(string n="msh", string ps="MSH$", void (*s)(Shell*)=0);
|
||||
string getPs() const;
|
||||
void setPs(const string &value);
|
||||
string getName() const;
|
||||
|
@ -57,8 +63,10 @@ public:
|
|||
void launch();
|
||||
|
||||
//for in-shell commands
|
||||
void addCmd(Command *cmd);
|
||||
size_t howManyCmds();
|
||||
void addCmd(Command *cmd, bool isThread=false);
|
||||
size_t howManyCmds() const;
|
||||
int executeCmd(vector<string>* args);
|
||||
int executeCmd(const string& args);
|
||||
|
||||
//exceptions
|
||||
class CommandsAlreadyCreatedException{};
|
||||
|
|
Loading…
Reference in a new issue