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

/*
 * This program accepts a single required argument: the string that
 * will be written into the pipe.
 */

int
main(int argc, char *argv[])
{
    int pfd[2];
    pid_t cpid;
    char buf;

    assert(argc == 2);

    /* The pipe system call creates two file descriptors and puts them
     * into the supplied array. The first file descriptor will be used for
     * reading, the second for writing. Whatever is written into the second
     * descritor can be read from the first one.
     */
    if (pipe(pfd) == -1)
    {
	    perror("pipe");
	    exit(EXIT_FAILURE);
    }

    cpid = fork();
    if (cpid == -1)
    {
	    perror("fork");
	    exit(EXIT_FAILURE);
    }

    if (cpid == 0)     /* Child reads from pipe */
    {
	    close(pfd[1]);          /* Close unused write end */

	    /* Read from the input end of the pipe until it is closed */
	    while (read(pfd[0], &buf, 1) > 0)
		    write(STDOUT_FILENO, &buf, 1);

	    write(STDOUT_FILENO, "\n", 1);
	    close(pfd[0]);
	    _exit(EXIT_SUCCESS);

    }
    else             /* Parent writes argv[1] to pipe */
    {
	    close(pfd[0]);          /* Close unused read end */

	    /* Let's enable this process to pass the information to the
	     * child by simply writing to stdout.
	     */
	    if(dup2(pfd[1], STDOUT_FILENO) == -1)
	    {
		    perror("dup2");
		    exit(EXIT_FAILURE);
	    }
	    close(pfd[1]);          /* We don't need it anymore */
	    write(STDOUT_FILENO, argv[1], strlen(argv[1]));
	    close(STDOUT_FILENO);   /* Reader will see EOF */
	    wait(NULL);             /* Wait for child */
	    exit(EXIT_SUCCESS);
    }
}

