Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 13
Hey all, I am writing my own shell and am trying to implement piping. The code should essentially perform command|command|command. It works fine if instead of forking to execvp the ...
  1. #1
    Just Joined!
    Join Date
    Apr 2008
    Posts
    7

    Implementing Piping Problem(URGENT)

    Hey all,
    I am writing my own shell and am trying to implement piping. The code should essentially perform command|command|command.
    It works fine if instead of forking to execvp the last command, I just do it and the shell exits, however I need to fork first. When i added that code, the shell hangs when i execute the command. I'm sure its something stupid and I just don't understand the file descriptors or wait() or something...
    :
    int pipe1[2], pipe2[2];

    pipe(pipe1);//create first pipe
    pid_t PID=fork();
    if(PID==0){
    close(1);
    dup(pipe1[1]);
    close(pipe1[0]);
    close(pipe1[1]);
    execvp(*argv,argv);
    printf("operation failed");

    } else {

    pipe(pipe2);
    pid_t PID2=fork();
    if (PID2==0) {
    close(0);
    dup(pipe1[0]);
    close(1);
    dup(pipe2[1]);
    close(pipe1[0]);
    close(pipe1[1]);
    close(pipe2[0]);
    close(pipe2[1]);
    execvp(*argv2, argv2);
    } else {
    pid_t PID3=fork();
    waitpid(PID3,&status,0);<-----Not sure about this
    if(PID3==0){
    close(0);
    dup(pipe2[0]);
    close(pipe1[0]);
    close(pipe1[1]);
    close(pipe2[0]);
    close(pipe2[1]);
    execvp(*argv3, argv3);
    }

    }
    }

  2. #2
    Just Joined! wildpossum's Avatar
    Join Date
    Apr 2008
    Location
    Sydney/Australia
    Posts
    92
    I think your going around this the wrong way. But *nix/Linux allows you to do it a number of ways. The most simple being;

    Generally you just write each individual process as a standalone shell script using input from fd0, output to fd1, errors to fd2. fd=file descriptor.

    Test each individual script by themselves, then put them together like so:

    At the command line you simply do "ProcessA | ProcessB | ProcessC"

    Where ProcessA places its input from fd0 or a file or where ever [fd?] you want it take input from), and outputs to the pipeA;

    ProcessB takes pipeA output as input, ProcessB outputs to pipeB input;

    ProcessC takes input from pipeB output and output its own to std output (usually fd1 or fd2).

    Pipes can be named pipes (i.e.: file on disk - but they are slow) or they are simply handles by your shell.

    Enjoy.

  3. #3
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    wildpossum, you are suggesting ways he can use the shell to pipe his processes together. The problem is that he's not using the shell, he's writing his own shell, obviously as a homework assignment.

    mtobin1897, look carefully at that final fork(). Suppose the return value of that fork() is zero, which means this is the parent process's final child. What does that final child do? Well, in your code, the first thing that child process does is a waitpid()! Since that child process has no children, the waitpid() will hang right there. I'm sure that's not your intent.

    Hope this helps.
    --
    Bill

    Old age and treachery will overcome youth and skill.

  4. #4
    Just Joined!
    Join Date
    Apr 2008
    Posts
    7
    haha yea it is a hw assignment, and I had an idea the problem was in there, however I am sure I need some sort of wait because if I remove the wait altogether the shell returns nothing but a new prompt, and if I put a waitpid(PID3,&status,0); after the if(PID3==0), so the parent only runs it, than my shell hangs..

  5. #5
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    if I put a waitpid(PID3,&status,0); after the if(PID3==0), so the parent only runs it, than my shell hangs.
    English is hopelessy imprecise. Can you show us your complete code exactly as you describe it in the above English description?
    --
    Bill

    Old age and treachery will overcome youth and skill.

  6. #6
    Just Joined!
    Join Date
    Apr 2008
    Posts
    7
    haha certainly,
    else {
    pid_t PID3=fork();
    waitpid(PID3,&status,0);<-----MOVE THIS
    if(PID3==0){
    close(0);
    dup(pipe2[0]);
    close(pipe1[0]);
    close(pipe1[1]);
    close(pipe2[0]);
    close(pipe2[1]);
    execvp(*argv3, argv3);
    }
    else{
    <----HERE
    }

  7. #7
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    Um, I wasn't asking just "where", I was asking "what". :)

    I need the complete code, please; in particular, everything you put inside that else clause. Not just the waitpid(), but everything else. I have some ideas, but I need to see what you have.
    --
    Bill

    Old age and treachery will overcome youth and skill.

  8. #8
    Just Joined!
    Join Date
    Apr 2008
    Posts
    7
    int pipe1[2], pipe2[2];

    pipe(pipe1);//create first pipe
    pid_t PID=fork();
    if(PID==0){
    close(1);
    dup(pipe1[1]);
    close(pipe1[0]);
    close(pipe1[1]);
    execvp(*argv,argv);
    printf("operation failed");

    } else {

    pipe(pipe2);
    pid_t PID2=fork();
    if (PID2==0) {
    close(0);
    dup(pipe1[0]);
    close(1);
    dup(pipe2[1]);
    close(pipe1[0]);
    close(pipe1[1]);
    close(pipe2[0]);
    close(pipe2[1]);
    execvp(*argv2, argv2);
    } else {
    pid_t PID3=fork();
    if(PID3==0){
    close(0);
    dup(pipe2[0]);
    close(pipe1[0]);
    close(pipe1[1]);
    close(pipe2[0]);
    close(pipe2[1]);
    execvp(*argv3, argv3);
    }
    else{
    wait(PID3, &status, 0);
    }

    }
    }
    type=0;
    numpipes=0;//random variable stuff
    background=0;
    do{cout<<"sish:>";//shell prompt
    gets(line);
    parse(line, argv, inputfileName,outputfileName, &type, &numpipes, argv2, argv3, &background);
    }while(*line=='\0');

  9. #9
    Just Joined!
    Join Date
    Apr 2008
    Posts
    7
    so to simplify things, I reduced it to only one pipe with the following code:

    int pipe1[2], pipe2[2];

    pipe(pipe1);//create first pipe
    pid_t PID=fork();
    if(PID==0){
    close(1);
    dup(pipe1[1]);
    close(pipe1[0]);
    close(pipe1[1]);
    execvp(*argv,argv);
    /* sort failed */
    printf("operation failed");

    } else {

    pipe(pipe2);
    pid_t PID2=fork();
    if (PID2==0) {
    close(0);
    dup(pipe1[0]);
    //close(1);
    //dup(pipe2[1]);
    close(pipe1[0]);
    close(pipe1[1]);
    //close(pipe2[0]);
    // close(pipe2[1]);
    execvp(*argv2, argv2);
    }else{
    wait(NULL);
    }
    do{cout<<"sish:>";
    gets(line);
    parse(line, argv, inputfileName,outputfileName, &type, &numpipes, argv2, argv3, &background);
    }while(*line=='\0');

    now it will display the shell prompt immediatly, however if I exit the shell by typing 'exit', the output is displayed followed by the exiting of the shell...

  10. #10
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    Are you sure that this most recent post is a fresh copy of your entire source?

    Because I can't get it to compile so I can play with it.

    For example, you don't define any sort of "parse" function anywhere, even though you call it, and you don't show me your #includes, if you even used any.

    I'm running out of time guessing what your code looks like. Maybe if you post the complete, accurate code, I'll have time to take a look at it. (I've taken too much time from other commitments as it is.) And before posting it, make sure that the version you post (a) compiles cleanly and (b) misbehaves the way you said it does. :)

    Sorry to be snippy and impolite, but I have limited time resources here. I do hope I have time to get back to this.
    --
    Bill

    Old age and treachery will overcome youth and skill.

Page 1 of 2 1 2 LastLast

Posting Permissions

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