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

#define BUFSIZE	1024

void die(char *msg)
{
  printf("%s\n", msg);
  exit(1);
}

void error(char *msg)
{
  perror(msg);
  exit(1);
}

void parent(pid_t child_pid, char *filename, int pfd[2])
{
  int status;
  char buf[BUFSIZE];
  int r ,w, t, fd = open(filename, O_RDONLY);
  if (fd < 0) error("open");
  close(pfd[0]);

  while((r = read(fd, buf, BUFSIZE)) > 0) {
    t = 0;
    do {
      w = write(pfd[1], buf+t, r-t);
      t += r;
    } while (t < r);
  }
  close(pfd[1]);
  close(fd);

  waitpid(child_pid, &status, 0);
  printf("Child exited with %d exit status\n", WEXITSTATUS(status));
}

void child(int pfd[2])
{
  close(pfd[1]);
  dup2(pfd[0], 0);
  close(pfd[0]);
  
  int fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
  if (fd < 0) error("open output.txt");
  dup2(fd, 1);
  dup2(fd, 2);
  close(fd);

  char *argv[2] = {"ppt", NULL};
  execve("/usr/games/ppt", argv, NULL);
  error("execve");
}

int main(int argc, char *argv[])
{
  if (argc < 2) die("Usage: pipe <filename>");
  char *filename = argv[1];

  int pfd[2];
  if (pipe(pfd) < 0) error("pipe");
  
  pid_t pid = fork();
  if (pid < 0) error("fork");

  if (pid > 0) parent(pid, filename, pfd);
  else child(pfd);
  
  return 0;
}
