Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdlib>
- #include <iostream>
- #include <string>
- #include <vector>
- #include <sstream>
- #include <cstring>
- #include <unistd.h>
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <stdio.h>
- using namespace std;
- class Cmd
- {
- public:
- vector<string> args;
- string input_rd_str;
- string output_rd_str;
- int input_rd;
- int output_rd;
- int input_fd;
- int output_fd;
- };
- void parse_and_run_command(const string &command) {
- /* TODO: Implement this. */
- /* Note that this is not the correct way to test for the exit command.
- For example the command " exit " should also exit your shell.
- */
- /* check for input length */
- if(command.length() > 100){
- cerr << "Input statement too long." << endl;
- return;
- }
- vector<string> tokens;
- string token;
- istringstream s(command);
- int num_commands = 1;
- while(s >> token){
- if(token == "|"){
- num_commands++;
- }
- tokens.push_back(token);
- }
- if(tokens[0] == "exit"){
- exit(0);
- }
- //string first_command = "";
- //vector <char *> argv;
- //int k = 0;
- /*if(tokens[0] != ">" && tokens[0] != "<"){
- //first_command = tokens[0];
- argv.push_back(&tokens[0][0]);
- k = 1;
- }
- else{
- //first_command = tokens[2];
- argv.push_back(&tokens[2][0]);
- * redirection code
- k = 3;
- }
- */
- vector<Cmd*> cmds;
- for(int a=0; a < num_commands; a++){
- cmds.push_back(new Cmd());
- }
- string input_redirection = "<DEF>";
- string output_redirection = "<DEF>";
- int num_input_rd = 0;
- int num_output_rd = 0;
- bool invalid = false;
- int cur_cmd = 0;
- vector<char *> all_args;
- for(size_t i=0; i < tokens.size(); i++){
- if(tokens[i] == "<"){
- /* do this */
- if(i == tokens.size()-1 || num_input_rd == 1){
- invalid = true;
- break;
- }
- else{
- string tkn = tokens[i+1];
- if(tkn == "<" || tkn == ">" || tkn == "|"){
- invalid = true;
- break;
- }
- input_redirection = tkn;
- num_input_rd++;
- i++;
- }
- }
- /* Check for output redirection */
- else if(tokens[i] == ">"){
- /* do this */
- if(i == tokens.size()-1 || num_output_rd == 1){
- invalid = true;
- break;
- }
- else{
- string tkn = tokens[i+1];
- if(tkn == "<" || tkn == ">" || tkn == "|"){
- invalid = true;
- break;
- }
- output_redirection = tkn;
- num_output_rd++;
- i++;
- }
- }
- else if(tokens[i] == "|"){
- if(i == tokens.size()-1){
- invalid = true;
- break;
- }
- if(cmds[cur_cmd]->args.size() == 0){
- invalid = true;
- break;
- }
- Cmd* cmd1 = cmds[cur_cmd];
- if(num_input_rd){
- cmd1->input_rd_str = input_redirection;
- }
- if(num_output_rd){
- cmd1->output_rd_str = output_redirection;
- }
- cmd1->input_rd = num_input_rd;
- cmd1->output_rd = num_output_rd;
- num_input_rd = 0;
- num_output_rd = 0;
- input_redirection = "<DEF>";
- output_redirection = "<DEF>";
- //if(cmds[cur_cmd]->args.size() == 0)
- cur_cmd++;
- }
- else{
- //argv.push_back(&tokens[i][0]);
- Cmd* cmd1 = cmds[cur_cmd];
- //cmd1->args.push_back(&tokens[i][0]);
- cmd1->args.push_back(tokens[i]);
- //cout << "PUSHED" << cmd1->args[cmd1->args.size()-1] << endl;
- all_args.push_back(&tokens[i][0]);
- }
- }
- Cmd* cmd_last = cmds[cur_cmd];
- if(num_input_rd){
- cmd_last->input_rd_str = input_redirection;
- }
- if(num_output_rd){
- cmd_last->output_rd_str = output_redirection;
- }
- cmd_last->input_rd = num_input_rd;
- cmd_last->output_rd = num_output_rd;
- if(cmd_last->args.size() == 0){
- invalid = true;
- }
- if(invalid){
- cerr << "Invalid command." << endl;
- return;
- }
- //cout << first_command << endl;
- //cout << arguments << endl;
- vector<int> pids;
- //int current_cmd = 0;
- //int pipefd[2] = {-1, -1};
- //int last_read = -1;
- //int output = -1;
- int last_read = -1;
- for(int i=0; i < num_commands; i++){
- int pipefd[2] = {-1, -1};
- //int last_read = -1;
- int input = -1;
- int output = -1;
- //int output = -1;
- //int pipefd[2];
- Cmd* cmd2 = cmds[i];
- /*if(cmd2->args[0] == "exit"){
- exit(0);
- }*/
- //int pipefd[2];i
- //if(pipe(pipefd) == -1){
- // cerr << "Out of file descriptors" << endl;
- //}
- if(i != 0){
- if(last_read < 0){
- cout << "ERROR" << endl;
- break;
- }
- else{
- input = last_read;
- last_read = -1;
- }
- }
- if(i < num_commands-1){
- if(pipe(pipefd) == -1){
- cerr << "Out of file descriptors" << endl;
- }
- //last_read = pipefd[0];
- //output = pipefd[1];
- output = pipefd[1];
- last_read = pipefd[0];
- //cout << "Create pipes i = " << i << " " << pipefd[0] << pipefd[1] << endl;
- }
- int pid = fork();
- if(pid < 0){
- cerr << strerror(errno) << endl;
- break;
- }
- if(pid == 0){
- if(last_read != -1){
- close(last_read);
- }
- //cout << "i" << i << endl;
- //cout << "ncmds" << num_commands << endl;
- //cout << "Close pipes child i = " << i << " " << pipefd[0] << endl;
- //close(pipefd[0]);
- if(i < num_commands-1){
- //cout << "Close pipes child i = " << i << " " << pipefd[1] << endl;
- dup2(pipefd[1], 1);
- close(pipefd[1]);
- }
- if(i != 0){
- //cout << "Close pipes child i = " << i << " " << last_read << endl;
- dup2(last_read, 0);
- close(last_read);
- }
- if(input >= 0){
- dup2(input, 0);
- close(input);
- }
- if(output >= 0){
- dup2(output, 1);
- close(output);
- }
- //cout << "Close pipes child i = " << i << " " << pipefd[1] << endl;
- //close(pipefd[1]);
- //cmd2->input_fd = 0;
- //cmd2->output_fd = 1;
- vector<string> args = cmd2->args;
- if(cmd2->input_rd == 1){
- int newfd = open(&cmd2->input_rd_str[0], O_RDONLY);
- dup2(newfd, 0);
- close(newfd);
- }
- if(cmd2->output_rd == 1){
- int newfd = open(&cmd2->output_rd_str[0], O_WRONLY | O_TRUNC | O_CREAT, 0777);
- dup2(newfd, 1);
- close(newfd);
- }
- //cout << cmd2->args[0] << endl;
- //cout << "output_rd: " << cmd2->output_rd << endl;
- //cout << "output_rd_str: " << cmd2->output_rd_str << endl;
- //cout << "input_rd: " << cmd2->input_rd << endl;
- //cout << "input_rd_str: " << cmd2->input_rd_str << endl;
- //cout << "CHECK" << endl;
- vector<char *> argv;
- for(size_t k = 0; k < args.size(); k++){
- //cout << args[k] << endl;
- string arg = args[k];
- char* copy_arg = new char[arg.size()+1];
- strcpy(copy_arg, arg.c_str());
- argv.push_back(copy_arg);
- //argv.push_back(&args[k][0]);
- }
- argv.push_back(NULL);
- execv(argv[0], &argv[0]);
- cerr << strerror(errno) << endl;
- cout << "Exec failed. Exiting..." << endl;
- exit(0);
- }
- else{
- //dup2(cmd2
- //cout << "Close pipes parent i = " << i << " " << pipefd[1] << endl;
- //cout << "Close pipes parent i = " << i << " " << last_read << endl;
- if(input >= 0){
- close(input);
- }
- if(output >=0){
- close(output);
- }
- //close(pipefd[1]);
- //cout << last_read << endl;
- //close(last_read);
- //last_read = pipefd[0];
- //int status;
- //waitpid(pid, &status, 0);
- //if(WIFSIGNALED(status)){
- // cout << cmds[i]->args[0] << " ended due to a signal." << endl;
- //}
- //else{
- // cout << cmds[i]->args[0] << " exit status: " << WEXITSTATUS(status) << endl;
- //}
- pids.push_back(pid);
- }
- }
- for(size_t j = 0; j < pids.size(); j++){
- int status;
- waitpid(pids[j], &status, 0);
- //if(WIFSIGNALED(status)){
- // cout << cmds[j]->args[0] << " ended due to a signal." << endl;
- //}
- //else{
- cout << cmds[j]->args[0] << " exit status: " << WEXITSTATUS(status) << endl;
- //}
- //delete cmds[j];
- }
- for(int b = 0; b < num_commands; b++){
- delete cmds[b];
- }
- }
- int main(void) {
- string command;
- cout << "> ";
- while (getline(cin, command)) {
- parse_and_run_command(command);
- std::cout << "> ";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement