Another pipe() problem.

This is a discussion on Another pipe() problem. within the C++ Programming forums, part of the General Programming Boards category; For some reason pipe() is returning an error when I try to pipe. Any idea why? Here's the code: Code: ...

  1. #1
    Registered User
    Join Date
    Sep 2005
    Posts
    41

    Another pipe() problem.

    For some reason pipe() is returning an error when I try to pipe. Any idea why? Here's the code:
    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];
       int pid;
       int len;
       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");
     
       vector<filedesc> p;
       //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 < commands.size() - 1; i++)
       {
          cout << "Pipe" << i << endl;
          if(pipe(p[i].desc) < 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)
    		{
    			cout << "exec left command" << endl;
    			char * tempstring;
    			tempstring = new char[commands[x].length() + 1];
    			strcpy(tempstring, commands[x].c_str());
    			command_toks.ParseAndAddTokens(tempstring);
    			len = command_toks[0].length();
    			const char * arg0 = command_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> args;
     
    			for(int j = 0; j < command_toks.GetNumTokens(); j++)
    			{
    				args.push_back(left_comm_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');
     
    			if(x == 0)
    			{
    				close(p[x].desc[0]);
    				dup2(p[x].desc[1], 1);
    				close(p[x].desc[1]);
    			}
    			else if(x==commands.size()-1)
    			{
    				close(p[x-1].desc[1]);
    				dup2(p[x-1].desc[0],0);
    				close(p[x-1].desc[0]);
    			}
    			else
    			{
    				for(int y = 0; y < commands.size() - 1; y++)
    				{
    					if(y == x-1)
    						close(p[y].desc[1]);
    					else if(y == x)
    						close(p[y].desc[0]);
    					else
    					{
    						close(p[y].desc[0]);
    						close(p[y].desc[1]);
    					}
    				}
     
    				dup2(p[x-1].desc[0],0);
    				close(p[x-1].desc[0]);
    				dup2(p[x].desc[1],1);
    				close(p[x].desc[1]);
    			}
     
     
    			execvp(arg0, &argv[0]); 
    			cerr << "Error on exec of " << arg0 << ": " << strerror(errno) << endl;
    			_exit(errno == ENOENT ? 127 : 126);
    		}
     
       }
     
       for(int z = 0; z < commands.size() - 1; z++)
       {
           close(p[z].desc[0]);
    	   close(p[z].desc[1]);
       }
     
       for(int zz = 0; zz < commands.size(); zz++)
           wait(0);   
    }
    heres the program output
    Code:
    dell1(22)>./mshell
    Pipe0
    Bad address

  2. #2
    Registered User
    Join Date
    Sep 2005
    Posts
    41
    changed the code to use 2d arrays
    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];
       int pid;
       int len;
       int status;
       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");
     
       //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 < commands.size() - 1; i++)
       {
          //if(pipe(p[i].desc) < 0)
    	  if(pipe(p[i]))
          {
             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)
    		{
    			cout << "executing command " << commands[x] << endl;
    			char * tempstring;
    			tempstring = new char[commands[x].length() + 1];
    			strcpy(tempstring, commands[x].c_str());
    			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;
    			if(x == 0)
    			{
    				cout << "freezes at first close" << endl;
    				close(p[x][0]);
    				dup2(p[x][1], 1);
    				close(p[x][1]);
    			}
    			else if(x==commands.size()-1)
    			{
    				cout << "freezes at second close" << endl;
    				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;
    }
    program freezes on the second interation of the loop that execvps.
    Last edited by LightsOut06; 10-28-2005 at 11:24 PM.

  3. #3
    Registered User
    Join Date
    Sep 2005
    Posts
    41
    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;
    }

  4. #4
    Registered User
    Join Date
    Sep 2005
    Posts
    41
    here's the output:

    Code:
    Pipe0
    got completed
    freeze before closes?
    freeze before closes?
    executing command ls
    freeze before dupes and closes?
    freezes at first close
    executing command grep main
    freeze before dupes and closes?
    freezes at second close
    freezes at exec
    dell1(115)>grep: (standard input): Input/output error

  5. #5
    Registered User
    Join Date
    Sep 2005
    Posts
    41
    i know this code is long, if anybody wants me to explain my thought process or something over aim or yim, pm me or something. I'm pretty desperate over here.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pipe(): Interprocess or Intraprocess comm?
    By @nthony in forum C Programming
    Replies: 2
    Last Post: 03-28-2007, 08:27 PM
  2. Pipe problem, popen(), pipe().
    By apacz in forum C Programming
    Replies: 7
    Last Post: 06-08-2006, 01:55 AM
  3. named pipe problem
    By fnoyan in forum Linux Programming
    Replies: 0
    Last Post: 05-28-2006, 06:54 AM
  4. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 05:46 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21