CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    Jan 2011
    Posts
    2

    Problem while execv for a program using PIPES

    Hi all,
    I am making a program for my class assignment related to PIPES.
    In the project i need to implement a remote shell server which can take 'piping' commands form the user.
    eg.
    ls | cat => as expected this will take output from ls into cat.
    The problem is that i did all the piping etc. But when i finally run the code and 'ls' is executed first and it pipes its data into 'PIPE' (fd=1) and in the next iteration, the forked process which executes CAT also has its stdin as PIPE's fd=0(i used dup2 to do copy the file descriptors).

    Now when finally the command is executed, CAT sends back the output as desired to the client but doesnot return for some reason(it just sleeps after sending the last line of output). The task manager in Ubuntu shows that its sleeping.
    Because I use wait() for the child process to exit...so my program gets stuck there.
    If I kill it from the task manager then the process returns to accept the next command but this problem has other effects which are not letting me finish my F##$#ing assigment.
    I am really REALLY stuck and all my work will go down the drain....your help will be very much appreciated.

    Where could I have been wrong :|

    Thanks.
    Pranay


    Below is the main function I am using(hope its not that messy )
    the struct command *comm -> this has the commands like LS and CAT stored in an array format.
    sub_comm_count = number of commands in a single like e.g ls | cat =>2 commands so its value= 1
    current_count = -1(at the first call)

    Also the program takes care of commands like
    ls > output.txt
    or cat < input.txt

    but these are not a problem right now


    void recursive_call(struct command *comm, int sub_comm_count,int current_count)
    {

    current_count++; // if current_count==sub_comm_count then no more commands to process
    int childpid;
    if( (childpid=fork()) <0)
    errlog("fork error");
    else if (childpid==0)
    {
    /***********************
    *child process - Recursive_call()
    **********************/
    int flag[4];
    flag[0]=flag[1]=flag[2]=flag[3]=0;
    int read_pipe,fd_prog_to_file,fd_file_to_prog;
    read_pipe=read_from_pipe(comm_count);// checks and copies the pipe fd to read pending data from
    if(read_pipe==1) flag[0]=1;
    if(read_pipe==-1)
    {
    //No PENDING pipe to read from
    /** check for '<' **/
    if (comm[current_count].file_to_program!=NULL)
    {
    if((fd_file_to_prog=open(comm[current_count].file_to_program,O_RDWR))==-1)
    {
    errlog("error opening 'read' file \n");
    exit(0);
    }
    flag[1]=1;
    // copy the file descriptor to the STDIN_FILENO
    if(dup2(fd_file_to_prog,STDIN_FILENO)!=STDIN_FILENO)
    {
    errlog("error in dup2\n");
    exit(0);
    }
    }
    }
    if(comm[current_count].pipe_level<0)
    {
    /** check for '>' **/
    if (comm[current_count].program_to_file!=NULL)
    {
    if((fd_prog_to_file=open(comm[current_count].program_to_file,O_WRONLY|O_CREAT, 0644))==-1)
    {
    errlog("error opening 'write' file \n");
    exit(0);
    }
    flag[2]=1;
    // copy the file descriptor to the STDOUT_FILENO
    if(dup2(fd_prog_to_file,STDOUT_FILENO)!=STDOUT_FILENO)
    {
    errlog("cannot dup2\n");
    exit(-1);
    }
    }
    else
    {
    /** OUTPUT TO client SOCKET ==default output **/
    ///CHANGE HERE SOCKET VALUE ---enter it from the funciton
    if( dup2(newsockfd,STDOUT_FILENO)!= STDOUT_FILENO )
    {
    errlog("dup 2 error");
    exit(-1);
    }

    }

    }else{
    close(pipe_from[comm[current_count].pipe_level + comm_count ][0]);
    /** handle '|' --> STDOUT DATA piped into some PIPE **/
    if( dup2(pipe_from[comm[current_count].pipe_level + comm_count ][1],STDOUT_FILENO)!= STDOUT_FILENO )
    {
    errlog("dup 2 error pipe out\n");
    exit(-1);
    }
    flag[3]=1;

    }
    /** execute the command **/

    execv(comm[current_count].argv1[0],comm[current_count].argv1);
    errlog("execv did not work \n");
    exit(-1 );

    }
    /***********************
    *Parent process - Recursive_call()
    **********************/
    int dummy;
    wait(&dummy);
    if(sub_comm_count>current_count)
    {

    comm_count++;
    recursive_call(comm,sub_comm_count,current_count);
    }
    else
    {
    return ;
    }
    }

  2. #2
    Join Date
    Jan 2011
    Posts
    2

    Re: Problem while execv for a program using PIPES

    Hi All,
    Thanks but my problem has been solved now.
    I was not able to get the EOF from the reading process as i had not closed all the write ends of my pipes.

    Thanks anyways..
    BR
    PRanay

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured