#!/bin/perl
# File: pipe_parent

# Dup (save) STDIN and STDOUT for later restoration to filenos 0 and 1
# --------------------------------------------------------------------
  open(SI, "<&STDIN");    # See Perl open() for ">&" semantics.
  open(SO, ">&STDOUT");

# Create a pipe on 0 and 1 for inheritance across fork
# No need to explicitly close STDIN and STDOUT.  Opening
# or creating a pipe on a filehandle closes it.
# ------------------------------------------------------
  pipe(STDIN, STDOUT);   # STDIN/STDOUT are read/write

# Start child, inheriting STDIN and STDOUT attached to pipe.
# ----------------------------------------------------------
  if (fork == 0) {
     exec("pipe_child") || die SO, "exec pipe_child failed: $!\n";
  }

# Close the write side of the pipe since we will not be writing to it,
# only reading from it.  We must close it so we can detect EOF when
# the child closes its write side.  The next read on a pipe after the
# last writer closes it will return EOF.
# --------------------------------------------------------------------
  close(STDOUT);           # Close write side of pipe (we *must*)
  open(STDOUT, ">&SO");    # Put stdout back (to screen probably)
  select STDOUT; $| = 1;   # And unbuffer it for timely messages

# Dup STDIN (the read side of the pipe) into another filehandle so we can
# put stdin back to where it was before we messed with it.
# -----------------------------------------------------------------------
  open(R, "<&STDIN");      # Dup stdin (read side) into new filehandle R
  open(STDIN, "<&SI");     # Put stdin back (to keyboard probably)

# Loop reading the pipe till EOF
# ------------------------------
  while ($r = <R>) {
     print "Parent read: $r"; 
  }
  print "Goodbye\n";
