/* popen.c (emx+gcc) */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/wait.h>

const char *text[] =
{
  "one", "two", "three", "four", "five", "six", "seven", NULL
};


static void usage (void)
{
  fputs ("Usage: popen -i[1] <command>\n"
         "       popen -o <command>\n"
         "       popen -f <file> <command>\n", stderr);
  exit (1);
}

int main (int argc, char *argv[])
{
  FILE *f, *feed;
  int c, i, j, mode, one;
  char buf[2048], *feed_fname;

  mode = 0; one = 0;
  while ((c = getopt (argc, argv, "fio1")) != -1)
    switch (c)
      {
      case 'f':
      case 'i':
      case 'o':
        if (mode != 0)
          usage ();
        mode = c;
        break;
      case '1':
        one = 1;
        break;
      default:
        usage ();
      }
  if (mode == 0 || (mode != 'i' && one) || argc - optind < 1)
    usage ();
  if (mode == 'f')
    {
      if (argc - optind < 2)
        usage ();
      feed_fname = argv[optind];
      feed = fopen (feed_fname, "rt");
      if (feed == NULL)
        {
          perror (feed_fname);
          return 2;
        }
      ++optind;
    }
  buf[0] = 0;
  for (i = optind; i < argc; ++i)
    {
      if (buf[0] != 0)
        strcat (buf, " ");
      strcat (buf, argv[i]);
    }
  if (mode == 'i')
    {
      f = popen (buf, "rt");
      if (f == NULL)
        {
          perror ("popen");
          return 2;
        }
      i = 1;
      while (fgets (buf, sizeof (buf), f) != NULL)
        {
          printf ("%4d: %s", i++, buf);
          if (one)
            break;
        }
    }
  else
    {
      f = popen (buf, "wt");
      if (f == NULL)
        {
          perror ("popen");
          return 2;
        }
      if (mode == 'f')
        {
          for (;;)
            {
              i = fread (buf, 1, sizeof (buf), feed);
              if (ferror (feed))
                {
                  perror (feed_fname);
                  return 2;
                }
              if (i == 0)
                break;
              j = fwrite (buf, 1, i, f);
              if (ferror (f))
                {
                  perror ("fwrite");
                  return 2;
                }
              if (j != i)
                {
                  fputs ("Pipe full\n", stderr);
                  break;
                }
            }
          fclose (feed);
        }
      else
        for (i = 0; text[i] != NULL; ++i)
          {
            if (fputs (text[i], f) != 0)
              {
                perror ("fputs");
                return 2;
              }
            if (fputc ('\n', f) == EOF)
              {
                perror ("fputc");
                return 2;
              }
            if (fflush (f) != 0)
              {
                perror ("fflush");
                return 2;
              }
          }
    }
  i = pclose (f);
  if (i < 0)
    {
      perror ("pclose");
      return 2;
    }
  if (WIFEXITED (i))
    printf ("Normal process termination, rc=%d\n", WEXITSTATUS (i));
  else if (WIFSTOPPED (i))
    printf ("Process stopped by signal %d\n", WSTOPSIG (i));
  else
    printf ("Process terminated by signal %d\n", WTERMSIG (i));
  return 0;
}
