All console functions previously labeled msh_* are now in Commands namespace

This commit is contained in:
Claudio Maggioni 2016-03-11 16:13:04 +01:00
parent 604f9cccb5
commit 6c010f3c50
7 changed files with 156 additions and 135 deletions

View File

@ -6,9 +6,11 @@ CONFIG -= qt
SOURCES += main.cpp \
command.cpp \
commands.cpp \
cmds.cpp
cmds.cpp \
console.cpp
HEADERS += \
command.h \
commands.h \
cmds.h
cmds.h \
console.h

View File

@ -21,9 +21,7 @@ int Cmds::exitExecute(const vector<string>*){
}
int Cmds::helpExecute(const vector<string>*){
int i;
cout << "Claudio Maggioni's msh\n" << endl
<< "Type program names and arguments, and hit enter.\n" << endl;
cout << "Msh info" << endl;
return 1;
}

View File

@ -17,7 +17,7 @@ void Commands::add(Command* cmd){
commands.push_back(cmd);
}
int Commands::howMany(){
size_t Commands::howMany(){
return commands.size();
}

View File

@ -15,7 +15,7 @@ class Commands
public:
Commands();
void add(Command*);
int howMany();
size_t howMany();
int launch(const vector<string>* args);
};

112
console.cpp Normal file
View File

@ -0,0 +1,112 @@
#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);
}

35
console.h Normal file
View File

@ -0,0 +1,35 @@
#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

130
main.cpp
View File

@ -2,143 +2,17 @@
* Edit of lsh from https://github.com/brenns10/msh.git rewritten in C++
* by Claudio Maggiobi
*/
#include <sys/wait.h>
#include <unistd.h>
#include "console.h"
#include <cstdlib>
#include <sstream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <iostream>
#include <csignal>
#include <commands.h>
using namespace std;
Commands cmds;
int msh_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 msh_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 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<string>* msh_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;
}
inline void msh_loop(void)
{
string* line;
vector<string>* 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();
Console::loop();
// Perform any shutdown/cleanup.