Pipes connecting 3 processes in a "circle"

I am trying to get a better understanding of pipes and processes. I have code in which I link 3 processes A,B,C. I have A->B->C but how would I go about getting C->A?

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
main()
{
pid_t A, B, C;
int fd[2];
int fd2[2];

if (pipe(fd) == -1)
{
    perror("pipe");
    exit(1);
}
B = fork();
if (B == -1)
{
    perror("fork");
    exit(2);
}
if (B == 0)
{
    if (pipe(fd2) == -1)
    {
        perror("pipe");
        exit(11);
    }
    C=fork();
    if(C == -1)
    {
        perror("fork 2");
        exit(22);
    }
    if (C == 0)
    {
        //i am C
        //do some stuff
    }
    else
    {
        //i am B
        //do some stuff
    }
}
else
{
    //i am A
    //do some stuff
}
   

Create absolutely everything you need in advance. Your child processes can pick what they need from it and close the rest.

int ab[2], bc[2], ca[2];
pipe(ab); pipe(bc); pipe(ca);

Each time you fork(), duplicate the appropriate ends of the pipe over stdin/stdout/etc and close all other pipes and copies.

You don't need to put if's inside if's inside if's to fork more than once. Just exit() at the bottom of the child code so it doesn't go places you don't want it to.

pid_t pid[3];
int n;

pid[0]=fork();
if(pid[0] == 0)
{
        // Process A reads from process C
        dup2(ca[0], STDIN_FILENO);
        // Process A writes to process B
        dup2(ab[1], STDOUT_FILENO);
        // Essential: close all other pipes and copies of pipes
        for(n=0; n<2; n++)
        { close(ab[n]); close(bc[n]); close(ca[n]); }

        // do whatever you want
        ...
        // quit so your child doesn't end up in the main program
        exit(0);
}

pid[1]=fork();
if(pid[1] == 0)
{
        // Process B reads from process A
        dup2(ab[0], STDIN_FILENO);
        // Process B writes to process C
        dup2(bc[1], STDOUT_FILENO);
        // Essential: close all other pipes and copies of pipes
        for(n=0; n<2; n++)
        { close(ab[n]); close(bc[n]); close(ca[n]); }

        // do whatever you want
        ...
        // quit so your child doesn't end up in the main program
        exit(0);
}

pid[2]=fork();
if(pid[2] == 0)
{
        // Process C reads from process B
        dup2(bc[0], STDIN_FILENO);
        // Process C writes to process A
        dup2(ca[1], STDOUT_FILENO);
        // Essential: close all other pipes and copies of pipes
        for(n=0; n<2; n++)
        { close(ab[n]); close(bc[n]); close(ca[n]); }

        // do whatever you want
        ...
        // quit so your child doesn't end up in the main program
        exit(0);
}

// Only the parent will be running outside of those if statements.
// Essential: close all other pipes and copies of pipes
for(n=0; n<2; n++)
{ close(ab[n]); close(bc[n]); close(ca[n]); }

for(n=0; n<3; n++)
{
        int status;
        waitpid(pid[n], &status, 0);
        printf("Child %d exited with status %d\n", n, WEXITSTATUS(status));
}