/***************************************************************************
 *   Copyright (C) 2005 by Brian Lauber   *
 *   bml8@case.edu   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


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

#include "blError.h"

int main(int argc, char **argv)
{
  const char *const c_message = " Child: ";
  const char *const p_message = "Parent: ";

  char buffer[64];       // The typed string will be stored / sent here
  int thePipe[2];        // Pipes are arrays of 2 file integers
  memset(buffer, 0, 64); // This will fill the buffer w/ 0's (Null-terminators)

  Error(pipe(thePipe));   // This will create a 2-ended pipe.
                          // thePipe[1] will be used to write
                          // thePipe[0] will be used to read

  // Now I will fork two processes.  Note that this will create
  // two distinct memory images of buffer[64].  In other words,
  // if child writes to buffer[64], this information will not be
  // reflected in the parent's buffer[64].  However, you could
  // copy the information from one process to another using a
  // pipe (which just so happens to be what this program will do!)
  if(Error(fork()) == 0) // Fork a child process
  {
    // Close the read end of the pipe since I am using a half-duplex pipe
    // (ie, the process can either read from the pipe or write to the pipe,
    //  but not both).
    Error(close(thePipe[0]));

    // This will write the contents of c_message to the standard output.
    Error(write(fileno(stdout), c_message, strlen(c_message)));

    // Read (at most) 64 characters from standard input (probably the keyboard)
    // and store them in buffer.  Input can be entered by typing and pressing
    // either [ENTER] or [CTR + D]
    Error(read(fileno(stdin), buffer, 64));

    // At this point, buffer[64] in the child contains the user input, but the
    // parent's copy of buffer[64] does not.  Therefore, we will send the child's
    // buffer[64] to the parent through a pipe.
    Error(write(thePipe[1], buffer, strlen(buffer)));
  }
  else // The parent process
  {
    // Close the write end of the pipe since I am assuming half-duplex mode
    Error(close(thePipe[1]));

    // Now the parent will wait until it receives information from the child.
    // The last parameter states that it will store at most 64 bytes into buffer[64]
    // (As opposed to insisting that it receives the entire 64 bytes)
    Error(read(thePipe[0], buffer, 64));

    // This will write the contents of p_message to the standard output.
    Error(write(fileno(stdout), p_message, strlen(p_message)));

    // Now the parent will write the contents of its buffer into the standard output.
    // Notice that buffer[64] now contains whatever was typed into the parent process!
    Error(write(fileno(stdout), buffer, strlen(buffer)));
  }

  return EXIT_SUCCESS;
}

