0
votes

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

1
You need 3 pipes to chain 4 commands. - eckes
Could you please elaborate taking account to the example I posted above? @eckes - Cows42
Your example uses fd[3] double. If you use fd[0] - fd[5] you have 6 fds by 3 pipes. The same 3 pipe symbol you use in your command. - eckes
I believe I fixed the example. So what I understand now, I should create amountOfCommands - 1 total pipes? So 5 commands would be 4 pipes, right? @eckes - Cows42
yes, you basically count the gaps in between commands. What you also could do is to actually create an array of fd-pairs, which is closer to the type Signature. Anyway you sample code is wrong as it does not use a offset into the array, pipe(fd) will only fill the first two slots - eckes

1 Answers

1
votes

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]);