Skip to content
Advertisement

Father-child process use pipe to talk, hangs after “execlp”, why?

I’ve got a simple text file called “tmp” under current directory, I wish to “cat” this file and then “sort” it, I want to use a c program to act like pipe “|” so I tried to use a father/child talk to do this.

Unexpectedly, the program hangs after “cat”, like below:

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
int main(){
    int pipefd[2];
    pipe(pipefd);
    int& readfd=pipefd[0];
    int& writefd=pipefd[1];

    pid_t pid=fork();
    if(pid==0){//child
        dup2(STDIN_FILENO,writefd);
        close(readfd);
        execlp("cat","cat","tmp",NULL);
        printf("child cat endsn");
        exit(0);
    }else{//father
        dup2(STDOUT_FILENO,readfd);
        close(writefd);
        execlp("sort","sort",NULL);
        printf("father sort endsn");
    }
    int status;
    wait(&status);
    printf("father existsn");
    return 0;
}

g++ to compile and run this file, after “cat” tihis file, I don’t even see “child cat ends”, it just hangs.

Where’s the problem, how to fix it? Thanks

Advertisement

Answer

1) The order of arguments in dup2 is incorrect. Look at dup2

2) parameters (stdin/stdout) to dup2 are incorrect.

3) The exec() family of functions replace the process image with a new one. So the code after that call does not get to run (unless the exec() fails), so I removed those.

Here is the code:

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

 int main(){
   int pipefd[2];
   pipe(pipefd);
   int& readfd = pipefd[0];
   int& writefd = pipefd[1];

   pid_t pid = fork();

   if(pid == 0){ //child
     dup2(writefd, 1);  // 1 is STDOUT_FILENO -- cat already has input -- needs output
     close(readfd);
     execlp("cat","cat","tmp.txt", NULL);
     perror("execlp() failed in child");

   }else{ //father
     dup2(readfd, 0); // 0 is STDIN_FILENO -- because sort needs input!
     close(writefd);
     execlp("sort","sort", NULL);
     perror("execlp() failed in parent");
   }
   return 0;
 }
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement