moved all console functions in class Shell
This commit is contained in:
parent
5445df8e3a
commit
be21596994
8 changed files with 155 additions and 100 deletions
6
Msh.pro
6
Msh.pro
|
@ -7,10 +7,10 @@ SOURCES += main.cpp \
|
||||||
command.cpp \
|
command.cpp \
|
||||||
commands.cpp \
|
commands.cpp \
|
||||||
cmds.cpp \
|
cmds.cpp \
|
||||||
console.cpp
|
shell.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
command.h \
|
command.h \
|
||||||
commands.h \
|
commands.h \
|
||||||
cmds.h \
|
shell.h \
|
||||||
console.h
|
cmds.h
|
||||||
|
|
8
cmds.cpp
8
cmds.cpp
|
@ -7,21 +7,21 @@ using namespace std;
|
||||||
|
|
||||||
int Cmds::cdExecute(const vector<string>* args){
|
int Cmds::cdExecute(const vector<string>* args){
|
||||||
if (args->operator[](1) == "\0") {
|
if (args->operator[](1) == "\0") {
|
||||||
cerr << "msh: expected argument to \"cd\"\n";
|
cerr << "expected argument to \"cd\"\n";
|
||||||
} else {
|
} else {
|
||||||
if (chdir(args->operator[](1).c_str()) != 0) {
|
if (chdir(args->operator[](1).c_str()) != 0) {
|
||||||
cerr << "msh";
|
cerr << "error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Cmds::exitExecute(const vector<string>*){
|
int Cmds::exitExecute(const vector<string>*){
|
||||||
std::exit(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Cmds::helpExecute(const vector<string>*){
|
int Cmds::helpExecute(const vector<string>*){
|
||||||
cout << "Msh info" << endl;
|
cout << " info" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
cmds.h
5
cmds.h
|
@ -1,9 +1,6 @@
|
||||||
/**
|
|
||||||
builtin commands
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CMDS_H
|
#ifndef CMDS_H
|
||||||
#define CMDS_H
|
#define CMDS_H
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -6,11 +6,6 @@ Commands::Commands()
|
||||||
{
|
{
|
||||||
if(created) throw CommandsAlreadyCreatedException();
|
if(created) throw CommandsAlreadyCreatedException();
|
||||||
created=true;
|
created=true;
|
||||||
|
|
||||||
//add builtin commands
|
|
||||||
add(new Command("cd", &cdExecute));
|
|
||||||
add(new Command("exit", &exitExecute));
|
|
||||||
add(new Command("help", &helpExecute));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Commands::add(Command* cmd){
|
void Commands::add(Command* cmd){
|
||||||
|
@ -22,7 +17,7 @@ size_t Commands::howMany(){
|
||||||
}
|
}
|
||||||
|
|
||||||
int Commands::launch(const vector<string>* args){
|
int Commands::launch(const vector<string>* args){
|
||||||
for(int i=0; i<commands.size(); i++){
|
for(unsigned int i=0; i<commands.size(); i++){
|
||||||
if((commands[i]->getName())==args->operator [](0)){
|
if((commands[i]->getName())==args->operator [](0)){
|
||||||
return commands[i]->execute(args);
|
return commands[i]->execute(args);
|
||||||
}
|
}
|
||||||
|
@ -32,5 +27,4 @@ int Commands::launch(const vector<string>* args){
|
||||||
|
|
||||||
bool Commands::created = false;
|
bool Commands::created = false;
|
||||||
|
|
||||||
//builtin commands
|
|
||||||
|
|
||||||
|
|
35
console.h
35
console.h
|
@ -1,35 +0,0 @@
|
||||||
#ifndef CONSOLE_H
|
|
||||||
#define CONSOLE_H
|
|
||||||
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <sstream>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <string>
|
|
||||||
#include <cstring>
|
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
#include <csignal>
|
|
||||||
#include <commands.h>
|
|
||||||
using std::cin;
|
|
||||||
using std::cout;
|
|
||||||
using std::cerr;
|
|
||||||
using std::string;
|
|
||||||
using std::vector;
|
|
||||||
using std::istringstream;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Console{
|
|
||||||
extern Commands cmds;
|
|
||||||
|
|
||||||
class IsUndoingLineException {};
|
|
||||||
|
|
||||||
int launch(vector<string>* args);
|
|
||||||
int execute(vector<string>* args);
|
|
||||||
void mshEofHandler(int);
|
|
||||||
string* read_line();
|
|
||||||
vector<string>* split_line(string* line);
|
|
||||||
void loop();
|
|
||||||
}
|
|
||||||
#endif // CONSOLE_H
|
|
26
main.cpp
26
main.cpp
|
@ -1,17 +1,27 @@
|
||||||
#include "console.h"
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include "shell.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "cmds.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace Cmds;
|
||||||
|
|
||||||
|
static void setup(Shell *);
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Load config files, if any.
|
string c = "msh-console-test";
|
||||||
|
string ps = "[msh-console-test]:";
|
||||||
// Run command loop
|
Shell mshConsoleTest(c, ps, &setup);
|
||||||
|
|
||||||
Console::loop();
|
|
||||||
|
|
||||||
// Perform any shutdown/cleanup.
|
|
||||||
|
|
||||||
|
//add builtin commands
|
||||||
|
mshConsoleTest.addCmd(new Command("cd", &cdExecute));
|
||||||
|
mshConsoleTest.addCmd(new Command("exit", &exitExecute));
|
||||||
|
mshConsoleTest.addCmd(new Command("help", &helpExecute));
|
||||||
|
mshConsoleTest.loop();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setup(Shell *){
|
||||||
|
cout << "Now entering in test shell...\n" << endl;
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,59 @@
|
||||||
#include "console.h"
|
#include "shell.h"
|
||||||
|
|
||||||
Commands Console::cmds;
|
string Shell::getPs() const
|
||||||
|
{
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
|
||||||
int Console::launch(vector<string>* args)
|
void Shell::setPs(const string &value)
|
||||||
|
{
|
||||||
|
ps = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
string Shell::getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shell::setName(const string &value)
|
||||||
|
{
|
||||||
|
name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shell::Shell( string n, string ps,void (*s)(Shell*)) : cmds()
|
||||||
|
{
|
||||||
|
shellSetup = s;
|
||||||
|
name = n;
|
||||||
|
this->ps = ps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shell::loop(){
|
||||||
|
//launch setup
|
||||||
|
if(shellSetup!=0) (*shellSetup)(this);
|
||||||
|
|
||||||
|
//launch loop
|
||||||
|
string* line;
|
||||||
|
vector<string>* args;
|
||||||
|
int status;
|
||||||
|
do {
|
||||||
|
bool readSuccess;
|
||||||
|
do{
|
||||||
|
cout << ps << " ";
|
||||||
|
try{
|
||||||
|
line = read_line();
|
||||||
|
readSuccess = true;
|
||||||
|
}
|
||||||
|
catch (IsUndoingLineException){
|
||||||
|
cout << "\n";
|
||||||
|
readSuccess = false;
|
||||||
|
}
|
||||||
|
}while(!readSuccess);
|
||||||
|
args = split_line(line);
|
||||||
|
status = execute(args);
|
||||||
|
} while (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Shell::launch(vector<string>* args)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
int status;
|
||||||
|
@ -17,13 +68,13 @@ int Console::launch(vector<string>* args)
|
||||||
}
|
}
|
||||||
argv[i] = NULL;
|
argv[i] = NULL;
|
||||||
if(execvp(argv[0], argv.data()) == -1) {
|
if(execvp(argv[0], argv.data()) == -1) {
|
||||||
cerr << "msh: command " << args->operator [](0) << " not found\n";
|
cerr << name <<": command " << args->operator [](0) << " not found\n";
|
||||||
}
|
}
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
else if (pid < 0) {
|
else if (pid < 0) {
|
||||||
// Error forking
|
// Error forking
|
||||||
cerr << "msh: error forking\n";
|
cerr << name <<": error forking\n";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Parent process
|
// Parent process
|
||||||
|
@ -34,7 +85,7 @@ int Console::launch(vector<string>* args)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Console::execute(vector<string>* args)
|
int Shell::execute(vector<string>* args)
|
||||||
{
|
{
|
||||||
if (args->operator [](0) == "\0") {
|
if (args->operator [](0) == "\0") {
|
||||||
// An empty command was entered.
|
// An empty command was entered.
|
||||||
|
@ -50,21 +101,22 @@ int Console::execute(vector<string>* args)
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shell::EofHandler(int){
|
||||||
|
|
||||||
bool undoingLine=false;
|
|
||||||
|
|
||||||
void Console::mshEofHandler(int){
|
|
||||||
undoingLine = true;
|
undoingLine = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
string* Console::read_line()
|
void setEofHandler(void (*funcptr)(int)){
|
||||||
{
|
|
||||||
string* buffer = new string();
|
|
||||||
struct sigaction *sa = new struct sigaction();
|
struct sigaction *sa = new struct sigaction();
|
||||||
sa->sa_handler = mshEofHandler;
|
sa->sa_handler = funcptr;
|
||||||
sa->sa_flags = 0; // not SA_RESTART!;
|
sa->sa_flags = 0; // not SA_RESTART!;
|
||||||
sigaction(SIGINT, sa, NULL);
|
sigaction(SIGINT, sa, NULL);
|
||||||
|
delete sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
string* Shell::read_line()
|
||||||
|
{
|
||||||
|
string* buffer = new string();
|
||||||
|
setEofHandler(EofHandler);
|
||||||
getline(cin,*buffer); // get command
|
getline(cin,*buffer); // get command
|
||||||
cin.clear(); // clear flags
|
cin.clear(); // clear flags
|
||||||
|
|
||||||
|
@ -72,11 +124,10 @@ string* Console::read_line()
|
||||||
undoingLine=false;
|
undoingLine=false;
|
||||||
throw IsUndoingLineException();
|
throw IsUndoingLineException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string>* Console::split_line(string* line)
|
vector<string>* Shell::split_line(string* line)
|
||||||
{
|
{
|
||||||
vector<string>* tokens = new vector<string>();
|
vector<string>* tokens = new vector<string>();
|
||||||
string ln = *line;
|
string ln = *line;
|
||||||
|
@ -89,24 +140,12 @@ vector<string>* Console::split_line(string* line)
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::loop(){
|
bool Shell::undoingLine = false;
|
||||||
string* line;
|
|
||||||
vector<string>* args;
|
void Shell::addCmd(Command* cmd){
|
||||||
int status;
|
cmds.add(cmd);
|
||||||
do {
|
}
|
||||||
bool readSuccess;
|
|
||||||
do{
|
size_t Shell::howManyCmds(){
|
||||||
cout << "MSH$ ";
|
return cmds.howMany();
|
||||||
try{
|
|
||||||
line = read_line();
|
|
||||||
readSuccess = true;
|
|
||||||
}
|
|
||||||
catch (IsUndoingLineException){
|
|
||||||
cout << "\n";
|
|
||||||
readSuccess = false;
|
|
||||||
}
|
|
||||||
}while(!readSuccess);
|
|
||||||
args = split_line(line);
|
|
||||||
status = execute(args);
|
|
||||||
} while (status);
|
|
||||||
}
|
}
|
50
shell.h
Normal file
50
shell.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef SHELL_H
|
||||||
|
#define SHELL_H
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
|
#include <csignal>
|
||||||
|
#include <commands.h>
|
||||||
|
using std::string;
|
||||||
|
using std::cin;
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
using std::istringstream;
|
||||||
|
using std::nullptr_t;
|
||||||
|
|
||||||
|
class Shell
|
||||||
|
{
|
||||||
|
static bool undoingLine;
|
||||||
|
Commands cmds;
|
||||||
|
string ps;
|
||||||
|
string name;
|
||||||
|
void (*shellSetup)(Shell *);
|
||||||
|
|
||||||
|
class IsUndoingLineException {};
|
||||||
|
|
||||||
|
int launch(vector<string>* args);
|
||||||
|
int execute(vector<string>* args);
|
||||||
|
static void EofHandler(int);
|
||||||
|
string* read_line();
|
||||||
|
vector<string>* split_line(string* line);
|
||||||
|
public:
|
||||||
|
Shell( string n="msh", string ps="MSH$",void (*s)(Shell*)=0);
|
||||||
|
string getPs() const;
|
||||||
|
void setPs(const string &value);
|
||||||
|
string getName() const;
|
||||||
|
void setName(const string &value);
|
||||||
|
void loop();
|
||||||
|
|
||||||
|
//for in-shell commands
|
||||||
|
void addCmd(Command *cmd);
|
||||||
|
size_t howManyCmds();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHELL_H
|
Loading…
Reference in a new issue