#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>

#define READ 0
#define WRITE 1

int main(int argc, char* argv[])
{
    int i, x=0, fdt1[2], fdt2[2], test, child_pid=0, nr_of_child = atoi(argv[1]);

    pid_t pid;

    if(pipe(fdt1) == -1 || pipe(fdt2) == -1)
    {
        perror("pipe failed"); exit(1);
    }


    switch(pid=fork())
    {

        case -1: perror("child b failed"); exit(1);

        case 0: //child b
                test = close(fdt1[WRITE]); assert(test==0);
                test = close(fdt2[READ]); assert(test==0);
                test = dup2(fdt1[READ],READ); assert(test==READ);
                test = dup2(fdt2[WRITE],WRITE); assert(test==WRITE);

                while(read(0,&x,sizeof(int)))
                {
                    child_pid=x+child_pid;
                }
                write(1,&child_pid,sizeof(int));
                test = close(fdt2[WRITE]); assert(test==0);
                test = close(fdt1[READ]); assert(test==0);

                sleep(4);

    }



    for(i = 0; i < nr_of_child; i++)
    {

        switch(pid=fork())
        {

            case -1: perror("child b failed"); exit(1);

            case 0: //child g
                    test = close(READ); assert(test==0);
                    test = close(fdt1[READ]); assert(test==0);
                    test = dup2(fdt1[WRITE],WRITE); assert(test==WRITE);
                    test = close(fdt2[READ]); assert(test==0);
                    test = close(fdt2[WRITE]); assert(test==0);
                    execlp("./g","./g",0);


        }

        wait(0);
    }


    system("ps -o pid,ppid,comm");
    sleep(1);
    system("ps -o pid,ppid,comm");
    sleep(1);
    system("ps -o pid,ppid,comm");
    sleep(1);

    test = close(WRITE); assert(test==0);
    test = dup2(fdt2[READ],READ); assert(test==READ);
    test = close(fdt1[READ]); assert(test==0);
    test = close(fdt1[WRITE]); assert(test==0);
    test = close(fdt2[WRITE]); assert(test==0);
    read(0,&child_pid,sizeof(int));
    printf("sum of pids: %d",child_pid);
    test = close(fdt2[READ]); assert(test==0);

    system("ps -o pid,ppid,comm");
    sleep(1);

}
