-3

Hi i was writing a program to do cat inputs.txt | sort | uniq in c programming using pipe, fork and dup2 but the program seems to not run any thing at all. I placed a printf at the beginning, right after main() and i do not see any output still.I have no idea what is going on in the background or why is this happening?

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main(){
    printf("we are here");
    int pipe1[2];
    int pipe2[2];
    if(pipe(pipe1)==-1){
        perror("failed to pipe\n");
        exit(1);
    }


    int process1=fork();

    if(process1<0){
        perror("failed to create the first child1\n");
        exit(1);
    }else if(process1>0){
        if(close(pipe1[0])==-1){
            perror("failed to close the first pipe read\n");
            exit(1);
        }

        if(dup2(pipe1[1],1)==-1){
            perror("failed to duplicate\n");
            exit(1);
        }

        if(close(pipe1[1])==-1){
            perror("failed to close the first pipe write\n");
            exit(1);
        }

        execlp("cat","cat","inputs.txt",NULL);
        perror("failed to exec\n");
        exit(1);
    }else if(process1==0){
        if(pipe(pipe2)==-1){
            perror("failed to pipe\n");
            exit(1);
        }

        int process2=fork();

        if(process2<0){
            perror("failed to create the first child1\n");
            exit(1);
        }else if(process2==0){

            if(close(pipe2[1])==-1){
                perror("failed to close the second pipe write-third process\n");
                exit(1);
            }

            if(dup2(pipe2[0],0)==-1){
                perror("failed to duplicate\n");
                exit(1);
            }

            if(close(pipe2[0])==-1){
                perror("failed to close the second pipe read-third process\n");
                exit(1);
            }

            execlp("uniq","uniq",NULL);
            perror("failed to exec\n");
            exit(1);
        }else if(process2>0){
            if(close(pipe1[1])==-1){
                perror("failed to close the first pipe write\n");
                exit(1);
            }
            if(close(pipe2[0])==-1){
                perror("failed to close the second pipe read\n");
                exit(1);
            }

            if(dup2(pipe1[0],0)==-1){
                perror("failed to duplicate\n");
                exit(1);
            }

            if(dup2(pipe2[1],1)==-1){
                perror("failed to duplicate\n");
                exit(1);
            }

            if(close(pipe1[0])==-1){
                perror("failed to close the first pipe read\n");
                exit(1);
            }

            if(close(pipe2[1])==-1){
                perror("failed to close the second pipe write\n");
                exit(1);
            }

            execlp("sort","sort",NULL);
            perror("failed to exec\n");
            exit(1);
        }
    }


}
  • Does your program hang or does it exit before outputting anything? – Martin Rosenau Aug 19 '18 at 18:11
  • 1
    Split the code into functions. Without splitting, it is too big with too much nesting to understand. Then move similar code into helper functions, and repost the question. In the process you may figure out what is wrong. – Michael Veksler Aug 19 '18 at 18:12
  • Side-note: `sort | uniq` (with no special arguments used for `uniq`) is better spelled as just `sort -u`, which has `sort` perform the uniquification (and more efficiently to boot, as it can dedup as it runs, which helps a lot if it ends up needing to spill to disk), avoiding the need to have two processes at all. – ShadowRanger Aug 19 '18 at 18:32
  • Please post a [mcve](https://stackoverflow.com/help/mcve) – ProXicT Aug 19 '18 at 22:22

1 Answers1

2
  1. printf doesn't actually print immediately -- it just puts stuff into a buffer to be printed later, either when the buffer fills or the process ends, or perhaps when a newline is put in the buffer. Since you do none of those things, it never appears. You can use fflush(stdout); to flush the buffer, and that is generally a good idea to do before calling fork if there might be buffered data -- otherwise the buffer will be forked and its contents may thus show up twice.

  2. You never close pipe1 in the grandchild before execing "uniq". Since pipe1 is the input to the "sort" program, it will never get an EOF, and sort will never terminate. Thus, you program seems to do nothing.

  3. "uniq" is running in the grandchild and outputting to stdout, which is (probably?) you terminal. If the parent (cat) exits first (which it likely will), the shell will get control again and may switch the controlling terminal out from under "uniq". That may cause uniq to be stopped, depeding on your terminal settings. By default, on most systems, that will not occur (uniq will just happily write to the terminal after the prompt from the shell, leading to a possibly confusing output_, but it could.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226