Reputation: 307
I'm working on an assignment which requires me to create a shell. I'm required to run most commands in an own process. However, the difficulty arises when I'm required to implement the piping between all the child processes.
From what I've understood so far is that I should create all the pipes in the parent process and then duplicate the pipes to STDIN/STDOUT. So I made a function that creates a new pipe for each command like this:
int count = 2 * amountOfCommands
int fd[count];
for (int i = 0; i < count; i++) {
pipe(fd); //I have error checking, but I left it out here.
}
Let us assume we are gonna create pipes for this example:
shell $> cat file.txt | grep 'pattern1' | grep 'pattern2' | wc -l
This means that we would create 4 pipes, so count would be 8. But I'm unsure on the copying part, does it end up like this:
Here I assume that 0 is STDIN_FILENO, 1 is STDOUT_FILNO, 2 is STDERR
cat file.txt
0: STDIN
1: fd[1] //WRITE
grep 'pattern1'
0: fd[0] //READ from cat
1: fd[3] //WRITE
grep 'pattern2'
0: fd[2] //READ from grep
1: fd[5] //WRITE
wc -l
0: fd[4] //READ from grep
1: STDOUT
If yes, what should I do with the rest of the pipes? I created 4 so there should be 4 READ and 4 WRITE. But when I connect them together, I only require 2 pipes? Am I thinking wrong somewhere?
Thank you
Upvotes: 0
Views: 92
Reputation: 10423
You need n-1
pipes for n
commands. When iterating to create the pipes you need to make sure to give a new 2-element int array (offset) to each call:
int pipes = numOfCommands - 1;
int fd[pipes][2];
for (int i=0;i<pipes;i++)
pipe(fd[i]);
Upvotes: 1