All console functions previously labeled msh_* are now in Commands namespace
This commit is contained in:
parent
604f9cccb5
commit
6c010f3c50
7 changed files with 156 additions and 135 deletions
6
Msh.pro
6
Msh.pro
|
@ -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
|
||||
|
|
4
cmds.cpp
4
cmds.cpp
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ void Commands::add(Command* cmd){
|
|||
commands.push_back(cmd);
|
||||
}
|
||||
|
||||
int Commands::howMany(){
|
||||
size_t Commands::howMany(){
|
||||
return commands.size();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
112
console.cpp
Normal 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
35
console.h
Normal 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
130
main.cpp
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in a new issue