int
main (int argc, char *argv[])
{
  const char *tr_program;
  const char *input_filename;
  size_t input_size;
  char *input;

  set_program_name (argv[0]);

  ASSERT (argc == 3);

  tr_program = argv[1];

  /* Read some text from a file.  */
  input_filename = argv[2];
  input = read_binary_file (input_filename, &input_size);
  ASSERT (input != NULL);

  /* Convert it to uppercase, line by line.  */
  {
    const char *argv[4];
    struct locals l;
    struct pipe_filter_gi *f;
    int result;

    l.input = input;
    l.nread = 0;

    argv[0] = tr_program;
    argv[1] = "abcdefghijklmnopqrstuvwxyz";
    argv[2] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    argv[3] = NULL;

    f = pipe_filter_gi_create ("tr", tr_program, argv, false, true,
                               prepare_read, done_read, &l);
    ASSERT (f != NULL);
    result = pipe_filter_gi_write (f, input, input_size);
    ASSERT (result == 0);
    result = pipe_filter_gi_close (f);
    ASSERT (result == 0);
    ASSERT (l.nread == input_size);
  }

  return 0;
}
int
main (int argc, char **argv)
{
  struct pipe_filter_gi *f;
  const char *path[] = { NULL, NULL };

  set_program_name (argv[0]);

  ASSERT (argc == 2);

  /* Test writing to a nonexistent program traps sooner or later.  */
  {
    int rc;

    path[0] = "/nonexistent/blah";
    f = pipe_filter_gi_create ("pipe-filter-test", path[0], path, true, false,
                               prepare_read, ignore_done_read, NULL);
    small_nap ();
    rc = pipe_filter_gi_write (f, "", 1);
    ASSERT (rc == 127 || rc == -1);
    rc = pipe_filter_gi_close (f);
    ASSERT (rc == 127 || rc == -1);
    printf ("Test 1 passed.\n");
    fflush (stdout);
  }

  /* Test returning the exit status.  */
  {
    path[0] = argv[1];
    f = pipe_filter_gi_create ("pipe-filter-test", path[0], path, false, false,
                               prepare_read, ignore_done_read, NULL);
    pipe_filter_gi_write_string (f, "1 -1");
    ASSERT (pipe_filter_gi_close (f) == 1);
    printf ("Test 2 passed.\n");
    fflush (stdout);
  }

  /* Same, but test returning the status in pipe_filter_gi_write.  */
  {
    int rc;

    path[0] = argv[1];
    f = pipe_filter_gi_create ("pipe-filter-test", path[0], path, false, false,
                               prepare_read, ignore_done_read, NULL);
    pipe_filter_gi_write_string (f, "1 -1\n"); /* tell the child to terminate */
    small_nap (); /* let the child terminate */
    rc = pipe_filter_gi_write (f, " ", 1); /* write to a closed pipe */
    ASSERT (rc == -1 && errno == EPIPE);
    /* Closing the filter must report same error again, for consistency with
       pipe_filter_ii_execute.  The subprocess' exit status is not returned.  */
    rc = pipe_filter_gi_close (f);
    ASSERT (rc == -1 && errno == EPIPE);
    printf ("Test 3 passed.\n");
    fflush (stdout);
  }

  /* Now test asynchronous I/O.  */
  {
    path[0] = argv[1];
    f = pipe_filter_gi_create ("pipe-filter-test", path[0], path, false, true,
                               prepare_read, output_done_read, NULL);
    pipe_filter_gi_write_string (f, "1 50\n");
    pipe_filter_gi_write_string (f, "51\n");
    pipe_filter_gi_write_string (f, "100");
    ASSERT (pipe_filter_gi_close (f) == 0);
    printf ("Test 4 passed.\n");
    fflush (stdout);
  }

  return 0;
}
static void
pipe_filter_gi_write_string (struct pipe_filter_gi *f, const char *string)
{
  pipe_filter_gi_write (f, string, strlen (string));
}