'C++ Pipe, dup2, execlp hangs
So I am trying to run 3 commands in a sequential way.
ls -l / | grep a | sort -r
However, my code seems to hang the process. I know that this usually indicated an unhandled pipe. but I can't seem to find the problem, I have closed all possible file descriptors that I could find.
Code may have some meaningless lines like closing the same FD twice, which I added while trying to fix it
#include <iostream>
#include<unistd.h>
#include <sys/wait.h>
using namespace std;
#define pipeWrite 1
#define pipeRead 0
// Main Function
int main() {
//Command to run: ls -l / | grep a | sort -r | wc > count.txt
// Total 4 commands to run, so 4 child processes.
pid_t c1,c2,c3,c4;
// File Descriptors
int pipeFD_1[2];
int pipeFD_2[2];
pipe(pipeFD_1);
// To execute ls -l
c1 = fork();
// Child
if (c1 == 0) {
// Closing input end
close(1);
dup(pipeFD_1[1]);
close(pipeFD_1[0]);
close(pipeFD_1[1]);
// Running command
execl("/bin/ls", "ls", "-l", "/",NULL);
}
pipe(pipeFD_2);
c2 = fork();
if (c2 == 0) {
// Closing output end
close(0);
dup(pipeFD_1[0]);
close(1);
dup(pipeFD_2[1]);
close(pipeFD_1[0]);
close(pipeFD_1[1]);
close(pipeFD_2[0]);
close(pipeFD_2[1]);
// Running command
execl("/bin/grep", "grep", "a", NULL);
}
//Closing pipe 1.
close(pipeFD_1[0]);
close(pipeFD_1[1]);
c3 = fork();
if (c3 == 0) {
// Closing out end
close(0);
dup(pipeFD_2[0]);
close(pipeFD_2[0]);
close(pipeFD_2[1]);
// Running command
execl("/bin/sort", "sort", "-r", NULL);
}
// Since exec auto exits the child process. No need to put else.
// Closing output end
waitpid(-1, NULL, 0);
waitpid(-1, NULL, 0);
waitpid(-1, NULL, 0);
exit(0);
}
EDIT: Fixed by adding 2 more lines after the third fork, closing FDs for pipe2 (for parent).
Solution 1:[1]
Thank you Barmar and ItsHoney for your valuable discussions. Posting them as answer to help other community members.
Fixed by adding 2 more lines after the third fork, closing FDs for pipe2 (for parent).
#include <iostream>
#include<unistd.h>
#include <sys/wait.h>
using namespace std;
#define pipeWrite 1
#define pipeRead 0
// Main Function
int main() {
//Command to run: ls -l / | grep a | sort -r | wc > count.txt
// Total 4 commands to run, so 4 child processes.
pid_t c1,c2,c3,c4;
// File Descriptors
int pipeFD_1[2];
int pipeFD_2[2];
pipe(pipeFD_1);
// To execute ls -l
c1 = fork();
// Child
if (c1 == 0) {
// Closing input end
close(1);
dup(pipeFD_1[1]);
close(pipeFD_1[0]);
close(pipeFD_1[1]);
// Running command
execl("/bin/ls", "ls", "-l", "/",NULL);
}
pipe(pipeFD_2);
c2 = fork();
if (c2 == 0) {
// Closing output end
close(0);
dup(pipeFD_1[0]);
close(1);
dup(pipeFD_2[1]);
close(pipeFD_1[0]);
close(pipeFD_1[1]);
close(pipeFD_2[0]);
close(pipeFD_2[1]);
// Running command
execl("/bin/grep", "grep", "a", NULL);
}
//Closing pipe 1.
close(pipeFD_1[0]);
close(pipeFD_1[1]);
c3 = fork();
if (c3 == 0) {
// Closing out end
close(0);
dup(pipeFD_2[0]);
close(pipeFD_2[0]);
close(pipeFD_2[1]);
// Running command
execl("/bin/sort", "sort", "-r", NULL);
}
// Since exec auto exits the child process. No need to put else.
// Closing output end
waitpid(-1, NULL, 0);
waitpid(-1, NULL, 0);
waitpid(-1, NULL, 0);
exit(0);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | MadhurajVadde-MT |
