bish/bish.cc

121 lines
3.6 KiB
C++
Raw Permalink Normal View History

2016-11-07 17:43:10 +00:00
// *************************
// Ben's Implemented SHell
// bish
// *************************
2016-10-28 16:37:30 +00:00
#include <iostream>
#include <string>
2016-10-31 00:21:39 +00:00
#include <unistd.h>
2016-10-31 15:50:03 +00:00
#include <vector>
#include <sys/wait.h>
#include <sys/types.h>
2016-11-04 20:52:10 +00:00
#include <fcntl.h>
2016-11-02 01:38:43 +00:00
#include <signal.h>
#include <sstream>
2016-11-04 20:52:10 +00:00
#include <pwd.h>
2016-11-02 01:38:43 +00:00
#include <readline/readline.h>
#include <readline/history.h>
2016-11-07 17:13:59 +00:00
#include "parse.h"
#include "util_fns.h"
2016-10-28 16:37:30 +00:00
using namespace std;
int main(int argc, char **argv){
2016-10-31 00:21:39 +00:00
2016-11-14 21:59:30 +00:00
signal(SIGINT, ctrlCHandler);
2016-11-10 17:49:06 +00:00
2016-11-14 21:59:30 +00:00
stringstream prompt;
static char* line = (char*)NULL;
2016-11-10 17:49:06 +00:00
2016-11-14 21:59:30 +00:00
const char *homedir;
if ((homedir = getenv("HOME")) == NULL) {
homedir = getpwuid(getuid())->pw_dir;
}
2016-11-12 02:49:32 +00:00
2016-11-14 21:59:30 +00:00
// set up history
using_history();
string histpath = string(homedir) + string("/.bish_history");
if (read_history(histpath.c_str())) {
cout << "history file not found. creating `~/.bish_history`." << endl;
int hist = open(histpath.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH);
close(hist);
}
2016-11-12 02:49:32 +00:00
2016-11-14 21:59:30 +00:00
int done = 0;
while (!done) {
2016-11-12 02:49:32 +00:00
2016-11-14 21:59:30 +00:00
prompt.str("");
prompt << "\e[34mbish:\e[92m" << get_current_dir_name() << "\e[34m:$\e[0m ";
2016-11-12 02:49:32 +00:00
2016-11-14 21:59:30 +00:00
line = readline(prompt.str().c_str());
if (line == NULL) break;
if (strcmp(line, "") == 0) continue;
if (line && *line) add_history (line);
2016-11-10 17:49:06 +00:00
2016-11-14 21:59:30 +00:00
// handle multiple commands w/ semicolon
2016-11-17 21:53:32 +00:00
vector<string> semicolon_split = split(line, ';');
for (auto semicolon_iter: semicolon_split) {
2016-11-03 18:45:41 +00:00
2016-11-17 21:53:32 +00:00
command *cmd = parse(split(semicolon_iter.c_str()));
2016-11-14 21:59:30 +00:00
int num_cmds = cmd->cmds.size();
// debug info
2016-11-16 18:24:42 +00:00
// print_cmd(cmd);
2016-11-03 21:59:20 +00:00
2016-11-16 18:24:42 +00:00
// clear line var cause we already parsed it
2016-11-14 21:59:30 +00:00
free(line);
line = (char*)NULL;
2016-10-31 17:53:32 +00:00
2016-11-14 21:59:30 +00:00
if (cmd->cmds[0].vargs[0] == "exit") {
done = 1;
break;
}
2016-11-03 21:59:20 +00:00
2016-11-16 21:32:42 +00:00
// COMMANDS that do something with the line before fork/exec
if (cmd->cmds[0].vargs[0] == "!") {
line = history_get(where_history())->line;
cout << line << endl;
cmd = parse(split(line));
}
2016-11-16 17:07:43 +00:00
if (num_cmds > 1) {
2016-11-17 21:53:32 +00:00
int in = 0, pipefd[2];
2016-11-16 17:07:43 +00:00
for (int i = 0; i < num_cmds-1; i++) {
2016-11-17 21:53:32 +00:00
if (pipe(pipefd)) perror("pipe");
2016-11-16 18:24:42 +00:00
cmd->cmds[i].ispipe = true;
2016-11-16 17:52:14 +00:00
cmd->cmds[i].infd = in;
2016-11-17 21:53:32 +00:00
cmd->cmds[i].outfd = pipefd[1];
2016-11-16 17:52:14 +00:00
expand_and_execute(&cmd->cmds[i]);
2016-11-17 21:53:32 +00:00
close(pipefd[1]);
in = pipefd[0];
2016-11-16 17:07:43 +00:00
}
if (in != 0) {
2016-11-16 18:24:42 +00:00
cmd->cmds[num_cmds-1].ispipe = true;
2016-11-16 17:52:14 +00:00
cmd->cmds[num_cmds-1].infd = in;
cmd->cmds[num_cmds-1].outfd = 1;
expand_and_execute(&cmd->cmds[num_cmds-1]);
2016-11-16 17:07:43 +00:00
}
}
2016-11-16 17:52:14 +00:00
else {
2016-11-16 18:24:42 +00:00
cmd->cmds[0].ispipe = false;
2016-11-16 17:52:14 +00:00
expand_and_execute(&cmd->cmds[0]);
}
2016-11-14 21:59:30 +00:00
// 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;
// }
// // do the thing to read the files
// }
// reset args array for the next prompt
delete cmd;
} // end ';' split
} // end main while loop
cout << endl;
if (write_history(histpath.c_str())) perror("write_history");
return 0;
2016-10-28 16:37:30 +00:00
}