#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/wait.h>

#define BUFSIZE	4096

typedef enum { P_READ = 0, P_WRITE = 1} dir_t;
pid_t pid;

// dir: 0 == 
int pipeopen(dir_t dir, char *cmd, ...)
{
  va_list ap;
  int max, p, pfd[2];
  char *s;
  
  if (pipe(pfd) < 0) return -1;
  pid = fork();
  if (pid < 0) return -1;
  if (pid) {
    close(pfd[1^dir]);
    return pfd[dir];
  }
  close(pfd[dir]);
  p = pfd[1^dir];
  dup2(p, 0);
  dup2(p, 1);
  dup2(p, 2);
  close(p);

  va_start(ap, cmd);
  char **args = malloc(sizeof(char *) * (max = 100));
  args[0] = strdup(cmd);
  for(p=1;;p++) {
    if (p == max-2) args = realloc(args, sizeof(char *) * (max += 100));
    s = va_arg(ap, char *);
    if (s == NULL) break;
    args[p] = s;
  }
  args[p] = NULL;
  execvp(cmd, args);
  perror("exec");
}

int pipeclose(int pfd)
{
  int status;
  close(pfd);
  waitpid(pid, &status, 0);
  return WEXITSTATUS(status);
}

int main(int argc, char *argv[])
{
   int r, pfd;
   char buf[BUFSIZE];
   
   pfd = pipeopen(P_READ, "false", "--help", NULL);
   if (pfd < 0) {
     perror("pipeopen");
     return 0;
   }
   while((r = read(pfd, buf, sizeof(buf))) > 0) {
     write(STDOUT_FILENO, buf, r);
   }
   printf("exited with %d\n", pipeclose(pfd));
   return 0;
}
