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

int i, pfd[2];

void alarm_handler(int signo)
{
  unsigned char x;

  i--;                     /* Decriment the global counter                   */
  x = i;                   /* Set the value we will pass down the pipe.      */
  printf("p(%d)", x);      /* Print out the parent() and what we are passing.*/
  fflush(stdout);          /* Force the write to stdout.                     */
  write(pfd[1], &x, 1);    /* Write a character to the pipe                  */
  alarm(1);                /* Set the alarm for another second from now      */
}

int main(int argc, char *argv[])
{
  int pid;
  unsigned char buf;
  size_t count;

  pipe(pfd);                                    /* Open a pipe               */

  pid = fork();                                 /* Fork here                 */

  switch(pid)
  {
  case -1:                                      /* -1 = failed fork          */
    printf("Failed to fork.\n");
    return(-1);
    break;
  case 0:                                       /* 0 = child                 */
    printf("Child up. Closing write descriptor.\n");
    close(pfd[1]);                              /* child READS               */
    while(1)
    {
      count = read(pfd[0], &buf, 1);            /* read on pipe blocks       */
      if(count < 1)                             /* count should be 1         */
      {
	printf("\nChild exits on dead parent.\n\n");
	return(0);
      }
      printf(" c(%d)\n", buf);
      fflush(stdout);
    }
    printf("\nChild exits normally.\n");       /* unreachable code           */
    break;
  default:                                     /* > 0 = parent               */
    i = 5;                                     /* parent runs 5 sec          */
    signal(SIGALRM, alarm_handler); 
    alarm(1);
    printf("Parent up. Closing read descriptor.\n");
    close(pfd[0]);                             /* parent WRITES in the alarm */
    while(i);                                  /* handler.                   */
    printf("\nParent quitting.\n");
    return(0);
    break;
  }
  return(0);
}