bish/bish.cc

197 lines
6.2 KiB
C++
Raw 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
vector<string> wfwe = split(line, ';');
for (auto it: wfwe) {
2016-11-03 18:45:41 +00:00
2016-11-14 21:59:30 +00:00
command *cmd = parse(split(it.c_str()));
int num_cmds = cmd->cmds.size();
// debug info
print_cmd(cmd);
2016-11-03 21:59:20 +00:00
2016-11-14 21:59:30 +00:00
// clear line var
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;
}
if (cmd->cmds[0].vargs[0] == "cd") {
if (cmd->cmds[0].vargs[1] == "") {
if (chdir(homedir) < 0) perror("chdir");
} else {
if (chdir(cmd->cmds[0].vargs[1].c_str()) < 0) perror("chdir");
}
}
2016-11-03 21:59:20 +00:00
2016-11-14 23:07:56 +00:00
// int n;
// bish_expandexec(&cmd->cmds[0]);
2016-11-14 21:59:30 +00:00
int in = 0, fd[2];
for (int i = 0; i < num_cmds-1; i++) {
pipe(fd);
2016-11-14 23:07:56 +00:00
dup_io(in, fd[1]);
2016-11-14 21:59:30 +00:00
bish_expandexec(&cmd->cmds[i]);
2016-11-14 23:07:56 +00:00
// close(fd[1]);
2016-11-14 21:59:30 +00:00
in = fd[0];
}
if (in != 0) {
dup_io(in, 1);
bish_expandexec(&cmd->cmds[num_cmds]);
}
2016-11-03 21:59:20 +00:00
2016-11-14 21:59:30 +00:00
// // else { // do fork/exec
// pid_t kidpid = fork();
// // fork error
// if (kidpid < 0) {
// perror("fork");
// return -1;
// }
// // run it
// // also check the path for things
// else if (kidpid == 0){
// int infd = 0, outfd = 1;
// if (num_cmds > 1) {
// int pipefd[2];
// pipe(pipefd);
// pid_t nextkidpid = fork();
// if (nextkidpid < 0) {
// perror("fork");
// return -1;
// }
// else if (nextkidpid == 0) {
// close(pipefd[0]);
// outfd = pipefd[1];
// bishexec(&curr, infd, outfd);
// }
// }
// // io redirection
// if (curr.outfile != "") {
// outfd = open(curr.outfile.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0644);
// if (outfd < 0) {
// perror("outfile");
// exit(0);
// }
// }
// if (curr.infile != "") {
// infd = open(curr.infile.c_str(), O_RDONLY);
// if (infd < 0) {
// perror("infile");
// exit(0);
// }
// }
// bishexec(&curr, infd, outfd);
// exit(1);
// } // end child
// // parent waits for kid to die
// else {
// int status;
// if (!cmd->background){
// do {
// if (waitpid(kidpid, &status, WUNTRACED | WCONTINUED) == -1) {
// perror("waitpid");
// exit(1);
// }
// if (WIFEXITED(status)) {
// cout << "(" << WEXITSTATUS(status) << "):";
// } else if (WIFSIGNALED(status)) {
// cout << endl << "killed by signal " << WTERMSIG(status) << endl;
// } else if (WIFSTOPPED(status)) {
// cout << endl << "stopped by signal " << WSTOPSIG(status) << endl;
// } else if (WIFCONTINUED(status)) {
// cout << endl << "continued" << endl;
// }
// } while (!WIFEXITED(status) && !WIFSIGNALED(status));
// }
// } // end parent
// COMMANDS that do something with the line before fork/exec
// 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->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
}