This commit is contained in:
Ben Harris 2016-11-10 23:29:05 -05:00
parent e32250ec1c
commit 4a3ed941b0
5 changed files with 79 additions and 50 deletions

44
bish.cc
View File

@ -64,14 +64,14 @@ int main(int argc, char **argv){
line = (char*)NULL;
// COMMANDS that do something with the line before fork/exec
if (strcmp(cmd->args[0], "!") == 0) {
if (strcmp(cmd->cmds[0]->args[0], "!") == 0) {
line = history_get(where_history())->line;
cout << line << endl;
cmd = parse(split(line));
}
else if (strcmp(cmd->args[0], ".") == 0 || strcmp(cmd->args[0], "source") == 0) {
int dotsrcfile = open(cmd->args[1], O_RDONLY);
else if (strcmp(cmd->cmds[0]->args[0], ".") == 0 || strcmp(cmd->cmds[0]->args[0], "source") == 0) {
int dotsrcfile = open(cmd->cmds[0]->args[1], O_RDONLY);
if (dotsrcfile < 0) {
perror("dotsrcfile");
continue;
@ -81,15 +81,15 @@ int main(int argc, char **argv){
// COMMANDS that skip fork/exec
// http://www.linuxquestions.org/questions/programming-9/making-a-c-shell-775690/
if (strcmp(cmd->args[0], "exit") == 0) break;
if (strcmp(cmd->cmds[0]->args[0], "exit") == 0) break;
// handle chdir
else if (strcmp(cmd->args[0], "cd") == 0) {
if (cmd->args[1] == NULL) {
else if (strcmp(cmd->cmds[0]->args[0], "cd") == 0) {
if (cmd->cmds[0]->args[1] == NULL) {
if (chdir(homedir) < 0) perror("chdir");
}
else {
if (chdir(cmd->args[1]) < 0) perror("chdir");
if (chdir(cmd->cmds[0]->args[1]) < 0) perror("chdir");
}
}
@ -106,43 +106,25 @@ int main(int argc, char **argv){
// run it
// also check the path for things
else if (kidpid == 0){
int infd = 0, outfd = 1;
// io redirection
if (cmd->outfile != "") {
int outfd = open(cmd->outfile.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0644);
if (cmd->cmds[0]->outfile != "") {
outfd = open(cmd->cmds[0]->outfile.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0644);
if (outfd < 0) {
perror("outfile");
exit(0);
}
if (dup2(outfd, 1) == -1) {
perror("dup2 outfile");
exit(0);
}
}
if (cmd->infile != "") {
int infd = open(cmd->infile.c_str(), O_RDONLY);
if (cmd->cmds[0]->infile != "") {
infd = open(cmd->cmds[0]->infile.c_str(), O_RDONLY);
if (infd < 0) {
perror("infile");
exit(0);
}
if (dup2(infd, 0) == -1) {
perror("dup2 infile");
exit(0);
}
}
// try to run it as is
execv(cmd->args[0], cmd->args);
// search the path
stringstream searchpath;
for (auto it: path) {
searchpath.str("");
searchpath << it << "/" << cmd->args[0];
execv(searchpath.str().c_str(), cmd->args);
}
// nothing found here...
cout << "that's not a command, bish" << endl;
bishexec(cmd, infd, outfd);
exit(1);
} // end child

View File

@ -11,17 +11,19 @@ using namespace std;
void print_cmd(command *cmd) {
if (cmd->background) cout << "backgroud: true" << endl;
if (cmd->piping != "") cout << "piping to: " << cmd->piping << endl;
if (cmd->infile != "") cout << "infile: " << cmd->infile << endl;
if (cmd->outfile != "") cout << "outfile: " << cmd->outfile << endl;
if (cmd->piping) cout << "piping to: " << cmd->piping << endl;
if (cmd->cmds[0]->infile != "") cout << "infile: " << cmd->cmds[0]->infile << endl;
if (cmd->cmds[0]->outfile != "") cout << "outfile: " << cmd->cmds[0]->outfile << endl;
}
command *parse(vector<string> args) {
command *parseinfo = new command();
bool in_flag = false, out_flag = false, piping_flag = false;
vector<string> cmd;
bool in_flag = false, out_flag = false;//, piping_flag = false;
vector<vector<string>> cmd;
int num_cmds = 0;
for (auto it: args) {
if (it == "<") {
@ -30,7 +32,7 @@ command *parse(vector<string> args) {
}
else if (in_flag) {
in_flag = false;
parseinfo->infile = it;
parseinfo->cmds[num_cmds]->infile = it;
}
else if (it == ">") {
@ -39,24 +41,34 @@ command *parse(vector<string> args) {
}
else if (out_flag) {
out_flag = false;
parseinfo->outfile = it;
parseinfo->cmds[num_cmds]->outfile = it;
}
else if (it == "|") {
piping_flag = true;
// piping_flag = true;
// cmd.push_back();
num_cmds++;
continue;
}
else if (piping_flag) {
piping_flag = false;
parseinfo->piping = it;
}
// else if (piping_flag) {
// // piping_flag = false;
// parseinfo->piping = true;
// }
else if (it == args.back() && it == "&") {
parseinfo->background = true;
}
else cmd.push_back(it);
else {
cmd[num_cmds].push_back(it);
}
}
parseinfo->args = v_to_cpp(cmd);
int i = 0;
for (auto it: cmd) {
parseinfo->cmds[i]->args = v_to_cpp(cmd[0]);
}
parseinfo->num_cmds = num_cmds;
return parseinfo;
}

13
parse.h
View File

@ -7,14 +7,19 @@
#include <vector>
using namespace std;
// command struct
struct command {
// simple_command struct
struct simple_command {
char** args;
bool background;
string piping;
string infile;
string outfile;
};
// command struct
struct command {
simple_command** cmds;
int num_cmds;
bool background;
bool piping;
};
// method definitions
void print_cmd(command *cmd);

View File

@ -6,7 +6,10 @@
#include <iostream>
#include <string.h>
#include <unistd.h>
// #include "util_fns.h"
#include <stdio.h>
#include <stdlib.h>
#include "parse.h"
#include "util_fns.h"
using namespace std;
@ -38,3 +41,29 @@ char** v_to_cpp(vector<string> vargs) {
}
void bishexec(command* cmd, int infd, int outfd) {
if (outfd != 1) {
if (dup2(outfd, 1) == -1) {
perror("dup2 outfile");
exit(0);
}
}
if (infd != 0) {
if (dup2(infd, 0) == -1) {
perror("dup2 infile");
exit(0);
}
}
// try to run it as is
execvp(cmd->cmds[0]->args[0], cmd->cmds[0]->args);
// search the path
// stringstream searchpath;
// for (auto it: path) {
// searchpath.str("");
// searchpath << it << "/" << cmd->args[0];
// execv(searchpath.str().c_str(), cmd->args);
// }
// nothing found here...
cout << "that's not a command, bish" << endl;
}

View File

@ -12,5 +12,6 @@ using namespace std;
void ctrlCHandler(int sig);
vector<string> split(const char *str, char c = ' ');
char** v_to_cpp(vector<string> vargs);
void bishexec(command* cmd, int infd, int outfd);
#endif