How to keep pipe FDs open even though parent process has their FDs closed?

120 Views Asked by At

I have to close pipe FDs of the process but I want them open in the child process. One solution could be to close FDs after fork() call. It offers solution if I have to call it once. I am calling this in a loop so even though I close FDs after fork(), it will work for first iteration. In the next iteration, it will again have theirs FDs closed. So how can I tackle a situation like this. The code in which I am trying to achieve this is as follows:

//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);
}
0

There are 0 best solutions below