Thread: Pipe problem, popen(), pipe().

  1. #1
    Registered User
    Join Date
    May 2005
    Posts
    76

    Pipe problem, popen(), pipe().

    Hello.
    I have to write program which reads a correct linux pipe for example:
    program1 | program2 | program3 | program 4
    and proceeds with pipes.
    I'm doing something like this:
    reading input.
    then i'm getting first command (i'm looking for the first '|'). Then I'm forking function with a string without begining (in the example above, im forking with string "program2 | program3 | program 4" and then in the parent i'm executing "program 1" with popen(). Then i'm reading the data from this pipe (what program1 returns) and then seding it to the child. Child recieves it. And here is my problem. Child has to run "program2" with everything what program1 sent. But I don't really know how to do this. I'm doing something like this: I have a string in which I have a "program2" + data which child received from parent and run it with popen(). But it doesn't seem to work like with an example:
    cat file | grep something.
    Is there any universal way to running programX with the data recieved from the parent?
    Regards,
    apacz
    Last edited by apacz; 06-07-2006 at 08:38 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    My guess would be to parse the command line and find that there are 'n' commands, and 'n-1' pipes.
    Create 'n-1' pipes using the pipe() system call, and create 'n' child processes using the fork() and execl() system calls.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2005
    Posts
    76
    Hello,
    I coded something like this:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    #define MAXLEN 1000    
    #define BUFSIZE 20     
    
    int main()
    {
            int     i,
                    j,
                    rec,
                    fd[2];
            char    tmp,
                    input_pipe[MAXLEN],
                    command[MAXLEN],
                    buf[BUFSIZE];
            i = 0;
            scanf("%c", &tmp);
            while(tmp != '\n')
            {
                    input_pipe[i] = tmp;
                    i++;
                    scanf("%c", &tmp);
            }
            input_pipe[i] = 0;
    
            pipe(fd);
    
            memset(command, 0, MAXLEN);
            j = 0;
    
            for(i = 0; i < strlen(input_pipe); i++)
            {
                    if(input_pipe[i] != '|')
                    {
                            command[j] = input_pipe[i];
                            j++;
                    }
                    else
                    {
                            command[j] = 0;
    
                            if(fork() == 0)
                            {
                                    dup2(fd[0], 0);
                                    dup2(fd[1], 1);
                                    system(command);                        
                            }
    
                            memset(command, 0, MAXLEN);
                            j = 0;
                    }
            }
            if(fork() == 0)
            {
                    dup2(fd[0], 0);
                    dup2(fd[1], 1);
                    system(command);
            }
    
            while((rec = read(fd[0], buf, BUFSIZE)) > 0)
                    write(1, buf, rec);
    
    
            return  0;
    }
    But it only work when I put no-pipe command like "cat file" but anyways program doesn't quit then. If I put command with a pipe it only executes what is before "|". Can anyone tell me what I'm doing wrong?
    --
    Regards,
    apacz

  4. #4
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    The first thing I would do is clean up all the compiler warnings. You're missing some pretty important header files. If you're not seing any compiler warnings then make sure you compile with -Wall.
    If you understand what you're doing, you're not learning anything.

  5. #5
    Registered User
    Join Date
    May 2005
    Posts
    76
    Thanks, you are right. I added:
    #include <unistd.h>
    #include <stdlib.h>
    but it doesn't solve the main problem.
    Regards,
    apacz

  6. #6
    Registered User
    Join Date
    May 2005
    Posts
    76
    I've also added wait() in parents' code:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    
    #define MAXLEN 1000     /* Maksymalna dlugosc input_pipeu */
    #define BUFSIZE 20      /* Rozmiar uzywanych buforow */
    
    int main()
    {
            int     i,
                    j,
                    rec,
                    status,
                    fd[2];
            char    tmp,
                    input_pipe[MAXLEN],
                    command[MAXLEN],
                    buf[BUFSIZE];
            i = 0;
            scanf("%c", &tmp);
            while(tmp != '\n')
            {
                    input_pipe[i] = tmp;
                    i++;
                    scanf("%c", &tmp);
            }
            input_pipe[i] = 0;
    
            pipe(fd);
    
            memset(command, 0, MAXLEN);
            j = 0;
    
            for(i = 0; i < strlen(input_pipe); i++)
            {
                    printf("%d\n", i);
                    if(input_pipe[i] != '|')
                    {
                            command[j] = input_pipe[i];
                            j++;
                    }
                    else
                    {
                            command[j] = 0;
    
                            /* printf("::%s\n", command);  */                       
                            if(fork() == 0)
                            {
                                    if(dup2(fd[0], 0) == -1)
                                            printf("dup2() error1\n");
                                    if(dup2(fd[1], 1) == -1)
                                            printf("dup2() error2\n");
                                    system(command);
                                    exit(5);
                            }
                            else
                            {
                                    wait(&status);
                                    memset(command, 0, MAXLEN);
                                    j = 0;
                            }
                    }
            }
            if(fork() == 0)
            {
                    dup2(fd[0], 0);
                    dup2(fd[1], 1);
                    system(command);
                    exit(6);
            }
            else
            {
                    wait(&status);
                    while((rec = read(fd[0], buf, BUFSIZE)) > 0)
                            write(1, buf, rec);
            }
    
    
            return  0;
    }
    But it's still the same :/
    Last edited by apacz; 06-07-2006 at 04:42 PM.

  7. #7
    Registered User
    Join Date
    May 2005
    Posts
    76
    Hello,
    I have next version of my program :
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    
    #define MAXLEN 1000     /* Maksymalna dlugosc input_pipeu */
    #define BUFSIZE 20      /* Rozmiar uzywanych buforow */
    
    
    int main()
    {
            int     i,
                    j,
                    rec,
                    status,
                    d = 0,
                    fd[2];
            char    tmp,
                    input_pipe[MAXLEN],
                    command[MAXLEN],
                    buf[BUFSIZE];
            i = 0;
            scanf("%c", &tmp);
            while(tmp != '\n')
            {
                    input_pipe[i] = tmp;
                    i++;
                    scanf("%c", &tmp);
            }
            input_pipe[i] = 0;
    
            pipe(fd);
    
            memset(command, 0, MAXLEN);
            j = 0;
    
            for(i = 0; i < strlen(input_pipe); i++)
            {
                    if(input_pipe[i] != '|')
                    {
                            command[j] = input_pipe[i];
                            j++;
                    }
                    else
                    {
                            command[j] = 0;                        
                            if(vfork() == 0)
                            {
                                    dup2(fd[0], 0);
                                    dup2(fd[1], 1);
                                    system(command);
                            }
                            else
                            {
                                    memset(command, 0, MAXLEN);
    
                                    j = 0;
                            }
                    }
            }
            if(fork() == 0)
            {
                    dup2(fd[0], 0);
                    dup2(fd[1], 1);
                    system(command);
            }
            else
            {
                    wait(&status);
                    close(fd[1]);
                    while((rec = read(fd[0], buf, BUFSIZE)) > 0)
                            write(1, buf, rec);
                    close(fd[0]);
            }
    
    
            return  0;
    }
    But it hangs on the second dup2() in the child code in for() loop... I have no clue why. Both dup2()s outside the for() works fine. Can anyone help?
    Regards,
    apacz

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Probably, but not till tomorrow when I'm back at my linux box..
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

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, 07:27 PM
  2. named pipe problem
    By fnoyan in forum Linux Programming
    Replies: 0
    Last Post: 05-28-2006, 05:54 AM
  3. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  4. Replies: 5
    Last Post: 11-07-2005, 11:34 PM
  5. Another pipe() problem.
    By LightsOut06 in forum C++ Programming
    Replies: 4
    Last Post: 10-29-2005, 10:38 PM