#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>

int main() {
    int pipefd[2];

    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    pid_t pf1 = fork();
    if (pf1 < 0) {
        perror("fork Pf1");
        exit(EXIT_FAILURE);
    }

    if (pf1 == 0) {
        pid_t pf1f1 = fork();
        if (pf1f1 < 0) {
            perror("fork Pf1f1");
            exit(EXIT_FAILURE);
        }

        if (pf1f1 == 0) {
            close(pipefd[1]);

            pid_t received_pid;
            while (1) {
                ssize_t bytesRead = read(pipefd[0], &received_pid, sizeof(pid_t));
                if (bytesRead == sizeof(pid_t)) {
                    printf("\t%d received %d\n", getpid(), received_pid);
                    fflush(stdout);
                } else if (bytesRead == 0) {
                    break;
                } else {
                    perror("read");
                    break;
                }
                sleep(1);
            }

            close(pipefd[0]);
            exit(EXIT_SUCCESS);
        } else {
            wait(NULL);
            exit(EXIT_SUCCESS);
        }

    } else {
        pid_t pf2 = fork();
        if (pf2 < 0) {
            perror("fork Pf2");
            exit(EXIT_FAILURE);
        }

        if (pf2 == 0) {
            close(pipefd[0]);

            pid_t my_pid = getpid();
            while (1) {
                ssize_t bytesWritten = write(pipefd[1], &my_pid, sizeof(pid_t));
                if (bytesWritten == sizeof(pid_t)) {
                    printf("%d sent %d\n", my_pid, my_pid);
                    fflush(stdout);
                } else {
                    perror("write");
                    break;
                }
                sleep(3);
            }

            close(pipefd[1]);
            exit(EXIT_SUCCESS);
        } else {
            wait(NULL);
            wait(NULL);
        }
    }

    return 0;
}

