/* Sample of creating a pipe that is used to
   connect STDOUT of one process to STDIN of another.

   This example runs ls and pipes the output to sort.
   Basic steps:

   1. A pipe is created.
   2. a child process is created (fork is called)
   3. The parent closes the reading end of the pipe
      and dups the writing end of the pipe to 1 (STDOUT).
   4. The child closes the writing end of the pipe
      and dups the reading end of the pipe to 0 (STDIN).
   5. The parent execs ls, and the child execs sort.

   NOTE: running this can result in seeing a new prompt from the
         shell before any of the output. The issue is that if the
         ls runs first and completes, the shell will see that it's child
         is done and print a new prompt. After this happens, the sort
         can get some cycles, process everything from the pipe and print
         it's results.

*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main(int argc, char **argv) {
  int fds[2];
  int pid;

  /* attempt to create a pipe  */
  if (pipe(fds)<0) {
	perror("Fatal Error");
	exit(1);
  }

  /* create another process */
  pid = fork();
  if (pid<0) {
	perror("Problem forking");
	exit(1);
  } else if (pid>0) {
	/* parent process */
	close(fds[0]);

	/* close stdout, reconnect to the writing end of the pipe */
	if ( dup2(fds[1],STDOUT_FILENO)<0) {
	  perror("can't dup");
	  exit(1);
	}

	execlp("ls","ls",NULL);
	perror("exec problem");
	exit(1);
  } else {
	/* child process */
	
	close(fds[1]);
	if (dup2(fds[0],STDIN_FILENO) < 0) {
	  perror("can't dup");
	  exit(1);
	}
	execlp("sort","sort",NULL);
	perror("exec problem");
	exit(1);
  }

  return(0);
}

