#include <errno.h>     // errno, EINTR
#include <stdio.h>     // perror
#include <stdlib.h>    // exit
#include <unistd.h>    // _exit, close, dup2, execl, fork, pipe, STDOUT_FILENO
#include <sys/wait.h>  // wait, pid_t


void handle_child_process_output(char *buffer, ssize_t count);

int main(void)
{
    int filedes[2];
    if (pipe(filedes) == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    pid_t pid = fork();
    if (pid == -1)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    else if (pid == 0)
    {
        while ((dup2(filedes[1], STDOUT_FILENO) == -1 && (errno == EINTR)))
        {
            continue;
        }
        fprintf(stdout,"point 1\n");

        close(filedes[1]);
        close(filedes[0]);
        fprintf(stdout,"point 2\n");

        static char *argv[] = {"echo", "Sphinx of black quartz, judge my vow.", NULL};
        execv("/bin/echo", argv);
        exit(EXIT_FAILURE); // only if execv fails
    }
    close(filedes[1]);

    // at this point filedes[1] is open in child process to be written in
    // and filedes[0] is open in parent process to be read from
    char buffer[4096];
    for (;;)
    {
        ssize_t count = read(filedes[0], buffer, sizeof(buffer));
        if (count == -1)
        {
            if (errno == EINTR)
            {
                continue;
            }
            else
            {
                perror("read");
                exit(EXIT_FAILURE);
            }
        }
        else if (count == 0)
        {
            break;
        }
        else
        {
            handle_child_process_output(buffer, count);
        }
    }
    close(filedes[0]);
    wait(NULL);
}

void handle_child_process_output(char *buffer, ssize_t count)
{
    printf("%s", "\x1b[34m");
    fwrite(buffer, count, sizeof(buffer[0]), stdout);
    printf("%s", "\x1b[0m");
}