This problem works with 2 piped commands (ie ls | grep main) but when I try to do more than 2 commands the program freezes.The int main() basically does the i/o and the execute command function is pretty much where im having all the problems. Thanks for any help. PS ParsedTokens is a class that parses completely the input. It puts the tokens in a vector of strings.
Code:// Program asks user for input and tries to execute linux commands based on that input // User can use multiple input piped commands ie ls | grep main | grep o. #define _GNU_SOURCE 1 #include <cstdio> #include <cstdlib> #include <cstring> #include <unistd.h> #include <getopt.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> #include <errno.h> #include <fcntl.h> #include "parsedTokens.h" #include <string> #include <iostream> #include <deque> using namespace std; void execute_command(string left_command, string right_command); int main() { char input[256]; string temp; string temp2; string temp3; ParsedTokens Tokens; unsigned int num_tokens; vector<string> commands; int len, len2; // get input cout << "enter text: "; cin.getline(input, 256, '\n'); Tokens.Clear(); Tokens.ParseAndAddTokens(input); cout << "you typed: " << input << endl; cout << "Parsed: " << endl; // lists parsed input for(unsigned int i = 0; i < Tokens.GetNumTokens(); i++) { cout << Tokens[i] << endl; } // puts the tokens (not including the "|") into a vector for(unsigned int i = 0; i < Tokens.GetNumTokens(); i++) { if(Tokens[i] != "|") { if(temp3.empty()) { temp3 = Tokens[i]; cout << "temp3: " << temp3 << endl; //if not at last token dont push but add the next token that isn't a pipe to temp3 if(i == Tokens.GetNumTokens() - 1) { commands.push_back(temp3); temp3.erase(0, temp3.length()); } else if(Tokens[i+1] == "|") // if the next token is a | then push token in temp3 { commands.push_back(temp3); temp3.erase(0, temp3.length()); } } else // if temp3 isn't empty then add space to temp3 and add next token to temp3 { temp3.insert(temp3.length()," "); temp3.insert(temp3.length(), Tokens[i]); cout << "temp3: " << temp3 << " after getting put together" << endl; if(i == Tokens.GetNumTokens() - 1) // if you're at last token then push { commands.push_back(temp3); temp3.erase(0, temp3.length()); } else if(Tokens[i+1] == "|") // if the next token is a | then push token in temp3 { commands.push_back(temp3); temp3.erase(0, temp3.length()); } } } /*else { commands.push_back(temp3); temp3.erase(0, temp3.length()); }*/ } cout << "all the commands to be executed" << endl; for(int i = 0; i < commands.size(); i++) cout << commands[i] << endl; //execute_command(commands[0], commands[1]); for(int i = 0; i < commands.size() - 1; i++) { cout << "left command: " << commands[i] << endl; cout << "right command: " << commands[i+1] << endl; execute_command(commands[i], commands[i+1]); } return 0; } void execute_command(string left_command, string right_command) { //char *argv[] = {"ls", "ls", 0}; //char *left_arg[] = {"ls", 0}; //char *right_arg[] = {"grep", "main", 0}; int p[2]; int pid; int len, len2; ParsedTokens left_comm_toks; ParsedTokens right_comm_toks; // int pipe(int filedes[2]); // filedes[0] is for reading, filedes[1] is for writing if(pipe(p) < 0) { cerr << strerror(errno) << endl; exit(EXIT_FAILURE); } pid = fork(); if(pid < 0) { cerr << strerror(errno) << endl; exit(EXIT_FAILURE); } if(pid == 0) { cout << "exec left command" << endl; char * tempstring; tempstring = new char[left_command.length() + 1]; strcpy(tempstring, left_command.c_str()); left_comm_toks.ParseAndAddTokens(tempstring); len = left_comm_toks[0].length(); const char * arg0 = left_comm_toks[0].c_str(); // converts left_command into left_argv[] which execvp uses /*len = left_command.length(); char * const myArr = new char[len + 1]; for(int x = 0; x < len; x++) myArr[x] = left_command[x]; myArr[len] = '\0'; char * const left_argv[] = {myArr,0};*/ delete [] tempstring; vector<string> left_args; for(int i = 0; i < left_comm_toks.GetNumTokens(); i++) { left_args.push_back(left_comm_toks[i]); } vector<char *> left_argv; for(int i = 0; i < left_args.size(); i ++) left_argv.push_back(const_cast<char *>(left_args[i].c_str())); left_argv.push_back('\0'); close(p[0]); dup2(p[1], 1); close(p[1]); //argv[2] = 0; // execvp(arg0, &left_argv[0]); cerr << "Error on exec of " << arg0 << ": " << strerror(errno) << endl; _exit(errno == ENOENT ? 127 : 126); } pid = fork(); if(pid < 0) { cerr << strerror(errno) << endl; exit(EXIT_FAILURE); } if(pid == 0) { cout << "executing right command" << endl; // converts left_command into left_argv[] which execvp uses /*len2 = right_command.length(); char * const myArr2 = new char[len +1]; for(int x = 0; x < len2; x++) myArr2[x] = right_command[x]; myArr2[len2] = '\0'; char *const right_argv[] = {myArr2, 0};*/ char * tempstring2; tempstring2 = new char[right_command.length() + 1]; strcpy(tempstring2, right_command.c_str()); right_comm_toks.ParseAndAddTokens(tempstring2); len = right_comm_toks[0].length(); const char * arg02 = right_comm_toks[0].c_str(); delete [] tempstring2; vector<string> right_args; for(int i = 0; i < right_comm_toks.GetNumTokens(); i++) { right_args.push_back(right_comm_toks[i]); } vector<char *> right_argv; for(int i = 0; i < right_args.size(); i ++) right_argv.push_back(const_cast<char *>(right_args[i].c_str())); right_argv.push_back('\0'); close(p[1]); dup2(p[0], 0); close(p[0]); //execvp(right_argv[0], right_argv); execvp(arg02, &right_argv[0]); cerr << "Error on exec of " << right_argv[0] << ": " << strerror(errno) << endl; _exit(errno == ENOENT ? 127 : 126); } close(p[0]); close(p[1]); wait(0); wait(0); }



LinkBack URL
About LinkBacks


