updated code still not working. I dont know what is wrong. I just cant get it working at all. Please any help or suggestions would be greatly appreciated. I've googled and googled, recoded and recoded. I cannot get this program to work.
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;
struct filedesc { int desc[2]; };
int main()
{
//char *argv[] = {"ls", "ls", 0};
//char *left_arg[] = {"ls", 0};
//char *right_arg[] = {"grep", "main", 0};
//int p[2];
pid_t pid;
int len;
int status;
int num_of_pipes;
int pipe_num = 0;
ParsedTokens left_comm_toks;
ParsedTokens right_comm_toks;
ParsedTokens command_toks;
vector<string> commands; // = {"ls", "grep main", "grep cpp"};
commands.push_back("ls");
commands.push_back("grep main");
//commands.push_back("grep cpp");
num_of_pipes = commands.size() - 1;
//vector<filedesc> p;
int (*p)[2];
p = new int[commands.size()][2];
//const int size = commands.size();
//int p[size][2];
// int pipe(int filedes[2]);
// filedes[0] is for reading, filedes[1] is for writing
for(int i = 0; i < num_of_pipes; i++)
{
//if(pipe(p[i].desc) < 0)
cout << "Pipe" << i << endl;
if(pipe(p[i]) < 0)
{
cerr << strerror(errno) << endl;
exit(EXIT_FAILURE);
}
cout << "got completed" << endl;
}
for(int x = 0; x < commands.size(); x++)
{
pid = fork();
if(pid < 0)
{
cerr << strerror(errno) << endl;
exit(EXIT_FAILURE);
}
if(pid == 0)
{
// parses command line and forms arg0, this block of code has been proven to work.
cout << "executing command " << commands[x] << endl;
char * tempstring;
tempstring = new char[commands[x].length() + 1];
strcpy(tempstring, commands[x].c_str());
command_toks.Clear();
command_toks.ParseAndAddTokens(tempstring);
len = command_toks[0].length();
const char * arg0 = command_toks[0].c_str();
delete [] tempstring;
vector<string> args;
for(int j = 0; j < command_toks.GetNumTokens(); j++)
{
args.push_back(command_toks[j]);
}
vector<char *> argv;
for(int k = 0; k < args.size(); k++)
argv.push_back(const_cast<char *>(args[k].c_str()));
argv.push_back('\0');
cout << "freeze before dupes and closes?" << endl;
// this stuff is what i think is wrong.
if(x == 0)
{
cout << "freezes at first close" << endl;
for(int y = 0; y < commands.size() - 1; y++)
{
if(y == 0)
close(p[y][0]); // pipe 0's read end is closed
else
{
close(p[y][0]); // close the rest, only pipe 0's we is open
close(p[y][1]);
}
}
dup2(p[x][1], 1);
close(p[x][1]);
}
else if(x==commands.size()-1)
{
cout << "freezes at second close" << endl;
for(int y = 0; y < commands.size() - 1; y++)
{
if(y == x-1)
close(p[y][1]); //close last pipes write end, leave last pipes read end open
else
{
close(p[y][0]); // close rest of the pipes, only last pipes read end open
close(p[y][1]);
}
}
//close(p[x-1][1]);
dup2(p[x-1][0],0);
close(p[x-1][0]);
}
else
{
cout << "freezes before loop" << endl;
for(int y = 0; y < commands.size() - 1; y++)
{
if(y == x-1)
close(p[y][1]);
else if(y == x)
close(p[y][0]);
else
{
close(p[y][0]);
close(p[y][1]);
}
}
cout << "freezes in last dupes" << endl;
dup2(p[x-1][0],0);
close(p[x-1][0]);
dup2(p[x][1],1);
close(p[x][1]);
}
cout << "freezes at exec" << endl;
execvp(arg0, &argv[0]);
cerr << "Error on exec of " << arg0 << ": " << strerror(errno) << endl;
_exit(errno == ENOENT ? 127 : 126);
cout << "freeze before wait?" << endl;
while(wait(&status) != pid);
}
cout << "freeze before closes?" << endl;
for(int z = 0; z < commands.size() - 1; z++)
{
close(p[z][0]);
close(p[z][1]);
}
}
for(int ii=0; ii<commands.size()-1; ii++)
delete [] p[ii];
// 2) when all arrays of columns are deleted
// for each row we can proceed with
// deleting the array of rows
delete [] p;
}