/* * * Hector Dominguez * * cs100 * hdomi001 * * */ #include #include #include #include #include #include #include #include #include #include #include using namespace std; int FOREGROUND_BACKGROUND = 0; void my_shell(); void error_checking(int check); void forking(int ampersand,int &argc, char** argv); int find_ampersand(string line); void do_work(int ampersand, int &argc, char** &argv, int fdr, int fdw); char** get_commands(int &argc, int &ersand); void build_argv(char** &commands, int &argc, int ampersand, char** &argv); char* search(char* command); int check_if_exist(char* path, char* cmd); char** get_Paths(int &size); void signal_handlers(int signal); int main() { signal(SIGINT, signal_handlers); while(true) my_shell(); return 0; } void my_shell() { int ampersand = 0; int argc = 0; char** commands = get_commands(argc, ampersand); char** argv = new char*[argc+1]; build_argv(commands, argc, ampersand, argv); } void signal_handlers(int signal) { if(FOREGROUND_BACKGROUND == 0) raise(SIGCONT); cout << endl; } //functions that exectes the commands void forking(int ampersand, int &argc, char** &argv, int fdr, int fdw) { char* command = new char; int pid = fork(); switch(pid) { case -1: cout << "error! failed\n"; break; case 0: FOREGROUND_BACKGROUND = 1; if(fdr != 0) dup2(fdr,0); if(fdw != 1) dup2(1,fdw); command = search(argv[0]); execv(command, argv); break; default: FOREGROUND_BACKGROUND = 0; if(ampersand == 0) waitpid(pid, 0, 0); break; } } //fuction that builds the array of pointers "argv" void build_argv(char** &commands, int &argc, int ampersand, char** &argv) { int newargc = 0; int reading = 0; if(argc == 1) { argv[newargc] = commands[0]; newargc++; argv[newargc] = NULL; forking(ampersand,newargc,argv,0,1); } else { argv[newargc] = commands[newargc]; newargc++; for( int i = 1; i < argc;++i) { string temp = commands[i]; if(temp == "<") { if(i == 1) continue; reading = open(commands[i+1], O_RDONLY); error_checking(reading); i++; } else if(temp == ">" ) { if(i == 1) continue; reading = open(commands[i-1], O_RDONLY); error_checking(reading); } else { argv[newargc] = commands[i]; newargc++; } } do_work(ampersand,newargc, argv, reading, 1); } } void do_work(int ampersand, int &argc, char** &argv, int fdr, int fdw) { argv[argc] = NULL; forking(ampersand, argc, argv, fdr, fdw); } char** get_commands(int &argc, int &ersand) { char** argv = new char*[256]; char* line = new char[256]; cout << "% " << flush; cin.getline(line,256, '\n'); char* temp = strtok(line, " "); string temp2 = temp; if(temp2 == "exit") exit(0); argv[argc] = temp; argc++; while((temp = strtok(NULL, " "))) { string amptemp = temp; if(amptemp == "&") ampersand = 1; argv[argc] = temp; argc++; } argv[argc] = NULL; return argv; } void error_checking(int check) { if(check == -1) { cout << "Unable to open file, use appropiate parameter\n\n"; exit(0); } } int find_ampersand(string line) { for(unsigned int i = 0; i < line.size(); ++i) if(line[i] == '&') return 1; return 0; } char** get_Paths(int &size) { char** paths = new char*[256]; char* path = getenv ("PATH"); char* temp = strtok(path, ":"); paths[size] = temp; size++; while((temp = strtok(NULL, ":"))) { paths[size] = temp; size++; } paths[size] = NULL; return paths; } int check_if_exist(char* path, char* cmd) { struct dirent *direntp; DIR *dirp = opendir(path); if(!dirp) return 0; while ((direntp = readdir(dirp))) { string s = direntp->d_name; if(s == cmd) return 1; } closedir(dirp); return 0; } char* search(char* command) { int counter = 0; char** Paths = get_Paths(counter); for(int i = 0; i < counter; ++i) { if(check_if_exist(Paths[i], command) == 1) { strcat(Paths[i],"/"); strcat(Paths[i],command); return Paths[i]; } } cout << "Command does not exist\n"; exit(0); }