(root)/
gettext-0.22.4/
gettext-tools/
gnulib-tests/
test-pipe-filter-ii2-main.c
       1  /* Test harness for pipe-filter-ii.
       2  
       3     Copyright (C) 2009-2023 Free Software Foundation, Inc.
       4     Written by Paolo Bonzini <bonzini@gnu.org>, 2009.
       5  
       6     This program is free software: you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation, either version 3 of the License, or
       9     (at your option) any later version.
      10  
      11     This program is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14     GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <config.h>
      20  
      21  #include "pipe-filter.h"
      22  
      23  #include <stdio.h>
      24  #include <errno.h>
      25  #include <unistd.h>
      26  #include <string.h>
      27  #include <signal.h>
      28  
      29  #include "binary-io.h"
      30  #include "full-write.h"
      31  #include "macros.h"
      32  
      33  struct locals
      34  {
      35    const char *input;
      36    size_t size;
      37    size_t nwritten;
      38    size_t nread;
      39    char buf[5];
      40  };
      41  
      42  static const void *
      43  prepare_write (size_t *num_bytes_p, void *private_data)
      44  {
      45    struct locals *l = (struct locals *) private_data;
      46    if (l->nwritten < l->size)
      47      {
      48        *num_bytes_p = l->size - l->nwritten;
      49        return l->input + l->nwritten;
      50      }
      51    else
      52      return NULL;
      53  }
      54  
      55  static void
      56  done_write (void *data_written, size_t num_bytes_written, void *private_data)
      57  {
      58    struct locals *l = (struct locals *) private_data;
      59    l->nwritten += num_bytes_written;
      60  }
      61  
      62  static void *
      63  prepare_read (size_t *num_bytes_p, void *private_data)
      64  {
      65    struct locals *l = (struct locals *) private_data;
      66    *num_bytes_p = sizeof (l->buf);
      67    return l->buf;
      68  }
      69  
      70  /* Callback that ignores the data that has been read.  */
      71  
      72  static void
      73  ignore_done_read (void *data_read, size_t num_bytes_read, void *private_data)
      74  {
      75  }
      76  
      77  /* Callback that outputs the data that has been read.  */
      78  
      79  static void
      80  output_done_read (void *data_read, size_t num_bytes_read, void *private_data)
      81  {
      82    full_write (STDOUT_FILENO, data_read, num_bytes_read);
      83  }
      84  
      85  int
      86  main (int argc, char **argv)
      87  {
      88    const char *path[] = { NULL, NULL };
      89  
      90    ASSERT (argc == 2);
      91  
      92    set_binary_mode (STDOUT_FILENO, O_BINARY);
      93  
      94    /* Test writing to a nonexistent program traps sooner or later.  */
      95    {
      96      struct locals l;
      97      int rc;
      98  
      99      l.input = "";
     100      l.size = 1;
     101      l.nwritten = 0;
     102      l.nread = 0;
     103      path[0] = "/nonexistent/blah";
     104      rc = pipe_filter_ii_execute ("pipe-filter-test", path[0], path, true, false,
     105                                   prepare_write, done_write,
     106                                   prepare_read, ignore_done_read,
     107                                   &l);
     108      ASSERT (rc == 127 || rc == -1);
     109      printf ("Test 1 passed.\n");
     110      fflush (stdout);
     111    }
     112  
     113    /* Test returning the exit status.  */
     114    {
     115      struct locals l;
     116      int rc;
     117  
     118      l.input = "1 -1";
     119      l.size = strlen (l.input);
     120      l.nwritten = 0;
     121      l.nread = 0;
     122      path[0] = argv[1];
     123      rc = pipe_filter_ii_execute ("pipe-filter-test", path[0], path, false, false,
     124                                   prepare_write, done_write,
     125                                   prepare_read, ignore_done_read,
     126                                   &l);
     127      ASSERT (rc == 1);
     128      printf ("Test 2 passed.\n");
     129      fflush (stdout);
     130    }
     131  
     132    /* Now test asynchronous I/O.  */
     133    {
     134      struct locals l;
     135      int rc;
     136  
     137      l.input = "1 50\n51\n100";
     138      l.size = strlen (l.input);
     139      l.nwritten = 0;
     140      l.nread = 0;
     141      path[0] = argv[1];
     142      rc = pipe_filter_ii_execute ("pipe-filter-test", path[0], path, false, true,
     143                                   prepare_write, done_write,
     144                                   prepare_read, output_done_read,
     145                                   &l);
     146      ASSERT (rc == 0);
     147      printf ("Test 3 passed.\n");
     148      fflush (stdout);
     149    }
     150  
     151    return 0;
     152  }