0

Hi I'm having a bit of trouble with my pipe execute function, where I want a shell in C to be able to execute a pipe. arg1 is the input before the pipe and arg2 is the command after the pipe. I want the program to terminate after ctr -d but it seems to quit without it, the moment the code is executed. An example of my input is ls | wc, where arg1 = ls and arg2 = wc. Any help/ pointers will be greatly appreciated, thank you.

int executepipe (char ** arg1, char ** arg2) {
    int fds[2];
    int child=-1;
    int status = pipe(fds);
    if (status < 0)
    {
        printf("\npipe error");
        return -1;
    }
    int pid =-1;
    pid= fork();    
    while(1){
    if (pid < 0) { //error!
        perror("fork");
        exit(1);
    } 
    //child
   if (pid == 0){// child process  (command after the pipe)
        //signal(SIGINT, SIG_DFL);
        //signal(SIGQUIT, SIG_DFL); 
        close(fds[1]);//nothing more to be written
        dup2(fds[0], 0);    
        execvp(arg2[0], arg2);
        
        //if errors exist execv wouldn't have been invoked
        perror("cannot execute command");
        exit(1);
    }
  
    else { // parent process  (command before the pipe)
        close(fds[0]); 
        signal(SIGINT, SIG_DFL);
        signal(SIGQUIT, SIG_DFL);
        dup2(fds[1], 1);
        close(fds[1]);
        execvp(arg1[0], arg1);
        //if errors exist execv wouldn't have been invoked
        perror("cannot execute command");
        exit(1);
           
    }
        if ( wait(&child) == -1 ){
            perror("wait");}
}
        return 0;
};
Jen123
  • 13
  • 2
  • 1
    Why is there a `while` loop as well as code after the `if`/`else` if all paths replace the current process? – Siguza May 22 '21 at 23:16
  • 1
    The first tip to debugging: ***Simplify!*** First reduce your program to the most minimal example that *doesn't* have the problem. Then add to your program a small piece at a time, build with extra warnings, and test. And if you get warning or any testing fails then fix that error first before continuing with the next small piece. – Some programmer dude May 22 '21 at 23:20
  • 1
    @Someprogrammerdude The "delete stuff until it works" approach can work wonders. Many editors have a quick "comment this block out" macro that makes this super easy in practice. – tadman May 22 '21 at 23:29
  • Thank you everyone I'll give that a shot. – Jen123 May 22 '21 at 23:34
  • You have a `while` loop? Why??? But, the `fork` is _above/outside_ the loop. As is the `pipe` call. So, I would expect this to go wrong on the 2nd iteration of the loop in the parent (i.e. the `pid` on the 2nd iteration is used/stale/invalid because of the `wait` on the 1st loop iteration). In other words, both the pipe `fds` and `pid` are invalid after the 1st iteration. – Craig Estey May 22 '21 at 23:45
  • Thanks @CraigEstey just got rid of it, I'll try my best to simplify things down so I can hopefully find the issues. I've spent too many days on this issue – Jen123 May 23 '21 at 00:38
  • There are many examples of custom shell pipes on SO. Here's one of my answers that may help a bit: https://stackoverflow.com/questions/52823093/fd-leak-custom-shell/52825582#52825582 – Craig Estey May 23 '21 at 00:53
  • After you dup, you typically close the fd. eg, the boiler plate is `dup2(fds[1], 1); close(fds[1]); exec` You don't need to keep both. – William Pursell May 23 '21 at 01:04

0 Answers0