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; }