//I want to execute pwd|sort > file.txt
char commands[2][30] = {"pwd", "sort"};
char directory [2][30] = {"/usr/bin/pwd", "/usr/bin/sort"}
char outputFile[30] = "file.txt"
int totalCommands = 2;
bool isOutputFilePresent = true;
//creating two pipes
int fd1[2];
int fd2[2];
pipe(fd1);
pipe(fd2);
//Closing the writing ends but keeping the reading ends open as closing them will destroy both the pipes
close (fd1[1]);
close (fd2[1]);
//loop to execute each command by creating a child process in each iteration
for (int i = 0; i < totalCommands; ++i)
{
pid_t pid = fork();
if (pid == 0)
{
if (i == totalCommands - 1)
{
if (i%2 == 0)
{
close(fd1[1]);
close(fd2[0]);
dup2(fd1[0], 0);
dup2(fd2[1], 1);
}
else
{
close(fd2[1]);
close(fd1[0]);
dup2(fd2[0], 0);
dup2(fd1[1], 1);
}
}
else
{
if (i%2 == 0)
{
close(fd2[0]);
close(fd2[1]);
close(fd1[1]);
dup2(fd1[0], 0);
}
else
{
close(fd1[0]);
close(fd1[1]);
close(fd2[1]);
dup2(fd2[0], 0);
}
if(isOutputFilePresent)
{
int outputFD = open (outputFile, O_WRONLY | O_CREAT);
dup2(outputFD, 1);
}
}
execv(directory[i], commands[i]) //ignore the fact that i am passing command name instead of argument vector
}
wait(NULL);
}
As the child process will inherit its own FDs of the pipe, I closed unused pipes in each process and by using dup2, assigned stdout and stdin FDs to it. But this code has a logical error and I guess its because of not using the pipes correctly. So where am I mistaken in the concept of pipes and what could be the solution to this problem. Thanks!
You close the write end of the pipes immediately after opening them. Therefore nothing can write to those pipes:
Do this:
Thus the child writes to A, and the parent reads from A. The parent writes to B, and the child reads from B.
The man page for pipe(2) give you example code that shows you how to do this: