ctrl c handler

This commit is contained in:
Ben Harris 2016-11-10 12:49:06 -05:00
parent 0f51870e63
commit 1dd3e2faec
4 changed files with 118 additions and 101 deletions

View File

@ -37,13 +37,13 @@ The Shell Assignment (total 42 points)
+ `ls a*b`
+ 1 ~~Knows how to change directory~~
+ `cd /fred`
+ 1 Bang last command
+ 1 ~~Bang last command~~
+ `!l` runs ls
+ 1 Bang # command
+ `!4` runs 4th command from history
+ 1 Queue commands
+ 1 ~~Queue commands~~
+ `make ; make install`
+ 1 Can have lots of semicolons
+ 1 ~~Can have lots of semicolons~~
+ `ls; sleep 3; rm fred`
+ 2 Change Prompt
+ `PS1="what is you command?"`
@ -69,7 +69,8 @@ The Shell Assignment (total 42 points)
+ 2 Only runs execuatables from an approved list
+ -2 Commands cannot have arguments (i.e. ls -l does not work).
13 pts
/20
Some cases to consider
+ A person tries to run a non-executable.

194
bish.cc
View File

@ -54,111 +54,131 @@ int main(int argc, char **argv){
// char **args = v_to_cpp(split(line));
// parse line
command *cmd = parse(split(line));
print_cmd(cmd);
// clear line var
free(line);
line = (char*)NULL;
vector<string> wfwe = split(line, ';');
for (auto it: wfwe) {
// http://www.linuxquestions.org/questions/programming-9/making-a-c-shell-775690/
if (strcmp(cmd->args[0], "exit") == 0) break;
// handle chdir
else if (strcmp(cmd->args[0], "cd") == 0) {
if (cmd->args[1] == NULL) {
if (chdir(homedir) < 0) perror("chdir");
}
else {
if (chdir(cmd->args[1]) < 0) perror("chdir");
}
}
command *cmd = parse(split(it.c_str()));
print_cmd(cmd);
// clear line var
free(line);
line = (char*)NULL;
// process the line.
else {
pid_t kidpid = fork();
// fork error
if (kidpid < 0) {
perror("fork");
return -1;
// COMMANDS that do something with the line before fork/exec
if (strcmp(cmd->args[0], "!") == 0) {
line = history_get(where_history())->line;
cmd = parse(split(line));
}
// run it
// also check the path for things
else if (kidpid == 0){
// io redirection
if (cmd->outfile != "") {
int outfd = open(cmd->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);
}
else if (strcmp(cmd->args[0], ".") == 0 || strcmp(cmd->args[0], "source") == 0) {
int dotsrcfile = open(cmd->args[1], O_RDONLY);
if (dotsrcfile < 0) {
perror("dotsrcfile");
continue;
}
if (cmd->infile != "") {
int infd = open(cmd->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;
exit(1);
// do the thing to read the files
}
// parent waits for kid to die
// 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;
// handle chdir
else if (strcmp(cmd->args[0], "cd") == 0) {
if (cmd->args[1] == NULL) {
if (chdir(homedir) < 0) perror("chdir");
}
else {
if (chdir(cmd->args[1]) < 0) perror("chdir");
}
}
// process the line.
else {
int status;
pid_t kidpid = fork();
// fork error
if (kidpid < 0) {
perror("fork");
return -1;
}
if (!cmd->background){
do {
if (waitpid(kidpid, &status, WUNTRACED | WCONTINUED) == -1) {
perror("waitpid");
exit(1);
// run it
// also check the path for things
else if (kidpid == 0){
// io redirection
if (cmd->outfile != "") {
int outfd = open(cmd->outfile.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0644);
if (outfd < 0) {
perror("outfile");
exit(0);
}
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;
if (dup2(outfd, 1) == -1) {
perror("dup2 outfile");
exit(0);
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
}
if (cmd->infile != "") {
int infd = open(cmd->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;
exit(1);
}
// 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));
}
}
}
// reset args array for the next prompt
delete cmd;
}
// reset args array for the next prompt
delete cmd;
}
cout << endl;
if (write_history(histpath.c_str())) perror("write_history");

View File

@ -10,14 +10,10 @@ using namespace std;
void print_cmd(command *cmd) {
// cout << "args: " << endl;
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;
cout << endl;
}

View File

@ -5,16 +5,13 @@
#include <signal.h>
#include <iostream>
#include <string.h>
#include <unistd.h>
// #include "util_fns.h"
using namespace std;
void ctrlCHandler(int sig) {
if (sig == SIGINT) {
// cout << "SIGINT received" << endl;
// return;
cout << endl;
}
cout << endl << "\e[34mbish:\e[92m" << get_current_dir_name() << "\e[34m:$\e[0m ";
}
// util methods
@ -23,7 +20,8 @@ vector<string> split(const char *str, char c) {
do {
const char *begin = str;
while (*str != c && *str) str++;
result.push_back(string(begin, str));
string tmp = string(begin, str);
if (tmp != "") result.push_back(tmp);
} while (0 != *str++);
return result;
}
@ -38,3 +36,5 @@ char** v_to_cpp(vector<string> vargs) {
args[vargs.size()] = NULL;
return args;
}