From cdd80339263e4137244de0181832b5bbbe1ccc5b Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Tue, 1 Nov 2016 21:38:43 -0400 Subject: [PATCH] use readline --- Makefile | 2 +- bish.cc | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 094a5e5..0aca48c 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CSW = -O3 -Wall -std=c++11 -ggdb -LSW = -std=c++11 +LSW = -lreadline all: make bish diff --git a/bish.cc b/bish.cc index 07e8a29..f9e8c08 100644 --- a/bish.cc +++ b/bish.cc @@ -6,8 +6,19 @@ #include #include #include +#include +#include +#include +#include +#include using namespace std; +// http://stackoverflow.com/questions/17766550/ctrl-c-interrupt-event-handling-in-linux +volatile sig_atomic_t flag = 0; +void ctrl_c_handler(int sig) { + flag = 1; +} + // util methods vector split(const char *str, char c = ' '){ vector result; @@ -26,8 +37,6 @@ char** parse_args(vector vargs) { args[i] = new char[vargs[i].size() + 1]; strcpy(args[i], vargs[i].c_str()); } - // use executable name as first - // strcpy(args[0], split(args[0], '/'),back().c_str()); args[vargs.size()] = nullptr; return args; } @@ -36,13 +45,28 @@ char** parse_args(vector vargs) { int main(int argc, char **argv){ string line; - int status; vector path = split(getenv("PATH"), ':'); - cout << "\e[92m" << get_current_dir_name() << " $\e[0m "; + // register ctrl c handler + signal(SIGINT, ctrl_c_handler); - while (getline(cin, line)) { - char **args = parse_args(split(line.c_str())); + stringstream prompt; + prompt << "\e[92m" << get_current_dir_name() << " $\e[0m "; + + static char* line_read = (char*)NULL; + while ((line_read = readline(prompt.str().c_str()))) { + + if (flag) { + printf("\n"); + continue; + flag = 0; + } + + char **args = parse_args(split(line_read)); + if (line_read) { + free(line_read); + line_read = (char*)NULL; + } // handle exit // http://www.linuxquestions.org/questions/programming-9/making-a-c-shell-775690/ @@ -88,6 +112,7 @@ int main(int argc, char **argv){ // parent waits for kid to die else { + int status; wait(&status); if (WIFEXITED(status)) { int exstatus = WEXITSTATUS(status); @@ -108,7 +133,7 @@ int main(int argc, char **argv){ } delete[] args; - cout << "\e[92m" << get_current_dir_name() << " $\e[0m "; + // cout << "\e[92m" << get_current_dir_name() << " $\e[0m "; } return 0; }