Home | History | Annotate | Line # | Download | only in testsuite
test-pexecute.c revision 1.1.1.2
      1      1.1  christos /* Pexecute test program,
      2  1.1.1.2  christos    Copyright (C) 2005-2017 Free Software Foundation, Inc.
      3      1.1  christos    Written by Ian Lance Taylor <ian (at) airs.com>.
      4      1.1  christos 
      5      1.1  christos    This file is part of GNU libiberty.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 2 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program; if not, write to the Free Software
     19      1.1  christos    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20      1.1  christos */
     21      1.1  christos 
     22      1.1  christos #ifdef HAVE_CONFIG_H
     23      1.1  christos #include "config.h"
     24      1.1  christos #endif
     25      1.1  christos #include "ansidecl.h"
     26      1.1  christos #include "libiberty.h"
     27      1.1  christos #include <stdio.h>
     28      1.1  christos #include <signal.h>
     29      1.1  christos #include <errno.h>
     30      1.1  christos #ifdef HAVE_STRING_H
     31      1.1  christos #include <string.h>
     32      1.1  christos #endif
     33      1.1  christos #include <sys/types.h>
     34      1.1  christos #ifdef HAVE_STDLIB_H
     35      1.1  christos #include <stdlib.h>
     36      1.1  christos #endif
     37      1.1  christos #ifdef HAVE_UNISTD_H
     38      1.1  christos #include <unistd.h>
     39      1.1  christos #endif
     40      1.1  christos #ifdef HAVE_SYS_WAIT_H
     41      1.1  christos #include <sys/wait.h>
     42      1.1  christos #endif
     43      1.1  christos #ifdef HAVE_SYS_TIME_H
     44      1.1  christos #include <sys/time.h>
     45      1.1  christos #endif
     46      1.1  christos #ifdef HAVE_SYS_RESOURCE_H
     47      1.1  christos #include <sys/resource.h>
     48      1.1  christos #endif
     49      1.1  christos 
     50      1.1  christos #ifndef WIFSIGNALED
     51      1.1  christos #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
     52      1.1  christos #endif
     53      1.1  christos #ifndef WTERMSIG
     54      1.1  christos #define WTERMSIG(S) ((S) & 0x7f)
     55      1.1  christos #endif
     56      1.1  christos #ifndef WIFEXITED
     57      1.1  christos #define WIFEXITED(S) (((S) & 0xff) == 0)
     58      1.1  christos #endif
     59      1.1  christos #ifndef WEXITSTATUS
     60      1.1  christos #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
     61      1.1  christos #endif
     62      1.1  christos #ifndef WSTOPSIG
     63      1.1  christos #define WSTOPSIG WEXITSTATUS
     64      1.1  christos #endif
     65      1.1  christos #ifndef WCOREDUMP
     66      1.1  christos #define WCOREDUMP(S) ((S) & WCOREFLG)
     67      1.1  christos #endif
     68      1.1  christos #ifndef WCOREFLG
     69      1.1  christos #define WCOREFLG 0200
     70      1.1  christos #endif
     71      1.1  christos 
     72      1.1  christos #ifndef EXIT_SUCCESS
     73      1.1  christos #define EXIT_SUCCESS 0
     74      1.1  christos #endif
     75      1.1  christos 
     76      1.1  christos #ifndef EXIT_FAILURE
     77      1.1  christos #define EXIT_FAILURE 1
     78      1.1  christos #endif
     79      1.1  christos 
     80      1.1  christos /* When this program is run with no arguments, it runs some tests of
     81      1.1  christos    the libiberty pexecute functions.  As a test program, it simply
     82      1.1  christos    invokes itself with various arguments.
     83      1.1  christos 
     84      1.1  christos    argv[1]:
     85      1.1  christos      *empty string*      Run tests, exit with success status
     86      1.1  christos      exit                Exit success
     87      1.1  christos      error               Exit error
     88      1.1  christos      abort               Abort
     89      1.1  christos      echo                Echo remaining arguments, exit success
     90      1.1  christos      echoerr             Echo next arg to stdout, next to stderr, repeat
     91      1.1  christos      copy                Copy stdin to stdout
     92      1.1  christos      write               Write stdin to file named in next argument
     93      1.1  christos */
     94      1.1  christos 
     95      1.1  christos static void fatal_error (int, const char *, int) ATTRIBUTE_NORETURN;
     96      1.1  christos static void error (int, const char *);
     97      1.1  christos static void check_line (int, FILE *, const char *);
     98      1.1  christos static void do_cmd (int, char **) ATTRIBUTE_NORETURN;
     99      1.1  christos 
    100      1.1  christos /* The number of errors we have seen.  */
    101      1.1  christos 
    102      1.1  christos static int error_count;
    103      1.1  christos 
    104      1.1  christos /* Print a fatal error and exit.  LINE is the line number where we
    105      1.1  christos    detected the error, ERRMSG is the error message to print, and ERR
    106      1.1  christos    is 0 or an errno value to print.  */
    107      1.1  christos 
    108      1.1  christos static void
    109      1.1  christos fatal_error (int line, const char *errmsg, int err)
    110      1.1  christos {
    111      1.1  christos   fprintf (stderr, "test-pexecute:%d: %s", line, errmsg);
    112      1.1  christos   if (errno != 0)
    113      1.1  christos     fprintf (stderr, ": %s", xstrerror (err));
    114      1.1  christos   fprintf (stderr, "\n");
    115      1.1  christos   exit (EXIT_FAILURE);
    116      1.1  christos }
    117      1.1  christos 
    118      1.1  christos #define FATAL_ERROR(ERRMSG, ERR) fatal_error (__LINE__, ERRMSG, ERR)
    119      1.1  christos 
    120      1.1  christos /* Print an error message and bump the error count.  LINE is the line
    121      1.1  christos    number where we detected the error, ERRMSG is the error to
    122      1.1  christos    print.  */
    123      1.1  christos 
    124      1.1  christos static void
    125      1.1  christos error (int line, const char *errmsg)
    126      1.1  christos {
    127      1.1  christos   fprintf (stderr, "test-pexecute:%d: %s\n", line, errmsg);
    128      1.1  christos   ++error_count;
    129      1.1  christos }
    130      1.1  christos 
    131      1.1  christos #define ERROR(ERRMSG) error (__LINE__, ERRMSG)
    132      1.1  christos 
    133      1.1  christos /* Check a line in a file.  */
    134      1.1  christos 
    135      1.1  christos static void
    136      1.1  christos check_line (int line, FILE *e, const char *str)
    137      1.1  christos {
    138      1.1  christos   const char *p;
    139      1.1  christos   int c;
    140      1.1  christos   char buf[1000];
    141      1.1  christos 
    142      1.1  christos   p = str;
    143      1.1  christos   while (1)
    144      1.1  christos     {
    145      1.1  christos       c = getc (e);
    146      1.1  christos 
    147      1.1  christos       if (*p == '\0')
    148      1.1  christos 	{
    149      1.1  christos 	  if (c != '\n')
    150      1.1  christos 	    {
    151      1.1  christos 	      snprintf (buf, sizeof buf, "got '%c' when expecting newline", c);
    152      1.1  christos 	      fatal_error (line, buf, 0);
    153      1.1  christos 	    }
    154      1.1  christos 	  c = getc (e);
    155      1.1  christos 	  if (c != EOF)
    156      1.1  christos 	    {
    157      1.1  christos 	      snprintf (buf, sizeof buf, "got '%c' when expecting EOF", c);
    158      1.1  christos 	      fatal_error (line, buf, 0);
    159      1.1  christos 	    }
    160      1.1  christos 	  return;
    161      1.1  christos 	}
    162      1.1  christos 
    163      1.1  christos       if (c != *p)
    164      1.1  christos 	{
    165      1.1  christos 	  snprintf (buf, sizeof buf, "expected '%c', got '%c'", *p, c);
    166      1.1  christos 	  fatal_error (line, buf, 0);
    167      1.1  christos 	}
    168      1.1  christos 
    169      1.1  christos       ++p;
    170      1.1  christos     }
    171      1.1  christos }
    172      1.1  christos 
    173      1.1  christos #define CHECK_LINE(E, STR) check_line (__LINE__, E, STR)
    174      1.1  christos 
    175      1.1  christos /* Main function for the pexecute tester.  Run the tests.  */
    176      1.1  christos 
    177      1.1  christos int
    178      1.1  christos main (int argc, char **argv)
    179      1.1  christos {
    180      1.1  christos   int trace;
    181      1.1  christos   struct pex_obj *test_pex_tmp;
    182      1.1  christos   int test_pex_status;
    183      1.1  christos   FILE *test_pex_file;
    184      1.1  christos   struct pex_obj *pex1;
    185      1.1  christos   char *subargv[10];
    186      1.1  christos   int status;
    187      1.1  christos   FILE *e;
    188      1.1  christos   int statuses[10];
    189      1.1  christos 
    190      1.1  christos   trace = 0;
    191      1.1  christos   if (argc > 1 && strcmp (argv[1], "-t") == 0)
    192      1.1  christos     {
    193      1.1  christos       trace = 1;
    194      1.1  christos       --argc;
    195      1.1  christos       ++argv;
    196      1.1  christos     }
    197      1.1  christos 
    198      1.1  christos   if (argc > 1)
    199      1.1  christos     do_cmd (argc, argv);
    200      1.1  christos 
    201      1.1  christos #define TEST_PEX_INIT(FLAGS, TEMPBASE)					\
    202      1.1  christos   (((test_pex_tmp = pex_init (FLAGS, "test-pexecute", TEMPBASE))	\
    203      1.1  christos     != NULL)								\
    204      1.1  christos    ? test_pex_tmp							\
    205      1.1  christos    : (FATAL_ERROR ("pex_init failed", 0), NULL))
    206      1.1  christos 
    207      1.1  christos #define TEST_PEX_RUN(PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME, ERRNAME)	\
    208      1.1  christos   do									\
    209      1.1  christos     {									\
    210      1.1  christos       int err;								\
    211      1.1  christos       const char *pex_run_err;						\
    212      1.1  christos       if (trace)							\
    213      1.1  christos 	fprintf (stderr, "Line %d: running %s %s\n",			\
    214      1.1  christos 		 __LINE__, EXECUTABLE, ARGV[0]);			\
    215      1.1  christos       pex_run_err = pex_run (PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME,	\
    216      1.1  christos 			     ERRNAME, &err);				\
    217      1.1  christos       if (pex_run_err != NULL)						\
    218      1.1  christos 	FATAL_ERROR (pex_run_err, err);					\
    219      1.1  christos     }									\
    220      1.1  christos   while (0)
    221      1.1  christos 
    222      1.1  christos #define TEST_PEX_GET_STATUS_1(PEXOBJ)					\
    223      1.1  christos   (pex_get_status (PEXOBJ, 1, &test_pex_status)				\
    224      1.1  christos    ? test_pex_status							\
    225      1.1  christos    : (FATAL_ERROR ("pex_get_status failed", errno), 1))
    226      1.1  christos 
    227      1.1  christos #define TEST_PEX_GET_STATUS(PEXOBJ, COUNT, VECTOR)			\
    228      1.1  christos   do									\
    229      1.1  christos     {									\
    230      1.1  christos       if (!pex_get_status (PEXOBJ, COUNT, VECTOR))			\
    231      1.1  christos 	FATAL_ERROR ("pex_get_status failed", errno);			\
    232      1.1  christos     }									\
    233      1.1  christos   while (0)
    234      1.1  christos 
    235      1.1  christos #define TEST_PEX_READ_OUTPUT(PEXOBJ)					\
    236      1.1  christos   ((test_pex_file = pex_read_output (PEXOBJ, 0)) != NULL		\
    237      1.1  christos    ? test_pex_file							\
    238      1.1  christos    : (FATAL_ERROR ("pex_read_output failed", errno), NULL))
    239      1.1  christos 
    240      1.1  christos   remove ("temp.x");
    241      1.1  christos   remove ("temp.y");
    242      1.1  christos 
    243      1.1  christos   memset (subargv, 0, sizeof subargv);
    244      1.1  christos 
    245      1.1  christos   subargv[0] = "./test-pexecute";
    246      1.1  christos 
    247      1.1  christos   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
    248      1.1  christos   subargv[1] = "exit";
    249      1.1  christos   subargv[2] = NULL;
    250      1.1  christos   TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL);
    251      1.1  christos   status = TEST_PEX_GET_STATUS_1 (pex1);
    252      1.1  christos   if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
    253      1.1  christos     ERROR ("exit failed");
    254      1.1  christos   pex_free (pex1);
    255      1.1  christos 
    256      1.1  christos   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
    257      1.1  christos   subargv[1] = "error";
    258      1.1  christos   subargv[2] = NULL;
    259      1.1  christos   TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL);
    260      1.1  christos   status = TEST_PEX_GET_STATUS_1 (pex1);
    261      1.1  christos   if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_FAILURE)
    262      1.1  christos     ERROR ("error test failed");
    263      1.1  christos   pex_free (pex1);
    264      1.1  christos 
    265      1.1  christos   /* We redirect stderr to a file to avoid an error message which is
    266      1.1  christos      printed on mingw32 when the child calls abort.  */
    267      1.1  christos   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
    268      1.1  christos   subargv[1] = "abort";
    269      1.1  christos   subargv[2] = NULL;
    270      1.1  christos   TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, "temp.z");
    271      1.1  christos   status = TEST_PEX_GET_STATUS_1 (pex1);
    272      1.1  christos   if (!WIFSIGNALED (status) || WTERMSIG (status) != SIGABRT)
    273      1.1  christos     ERROR ("abort failed");
    274      1.1  christos   pex_free (pex1);
    275      1.1  christos   remove ("temp.z");
    276      1.1  christos 
    277      1.1  christos   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
    278      1.1  christos   subargv[1] = "echo";
    279      1.1  christos   subargv[2] = "foo";
    280      1.1  christos   subargv[3] = NULL;
    281      1.1  christos   TEST_PEX_RUN (pex1, 0, "./test-pexecute", subargv, NULL, NULL);
    282      1.1  christos   e = TEST_PEX_READ_OUTPUT (pex1);
    283      1.1  christos   CHECK_LINE (e, "foo");
    284      1.1  christos   if (TEST_PEX_GET_STATUS_1 (pex1) != 0)
    285      1.1  christos     ERROR ("echo exit status failed");
    286      1.1  christos   pex_free (pex1);
    287      1.1  christos 
    288  1.1.1.2  christos   /* Check empty parameters don't get lost.  */
    289  1.1.1.2  christos   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
    290  1.1.1.2  christos   subargv[1] = "echo";
    291  1.1.1.2  christos   subargv[2] = "foo";
    292  1.1.1.2  christos   subargv[3] = "";
    293  1.1.1.2  christos   subargv[4] = "bar";
    294  1.1.1.2  christos   subargv[5] = NULL;
    295  1.1.1.2  christos   TEST_PEX_RUN (pex1, 0, "./test-pexecute", subargv, NULL, NULL);
    296  1.1.1.2  christos   e = TEST_PEX_READ_OUTPUT (pex1);
    297  1.1.1.2  christos   CHECK_LINE (e, "foo  bar");  /* Two spaces!  */
    298  1.1.1.2  christos   if (TEST_PEX_GET_STATUS_1 (pex1) != 0)
    299  1.1.1.2  christos     ERROR ("echo exit status failed");
    300  1.1.1.2  christos   pex_free (pex1);
    301  1.1.1.2  christos 
    302      1.1  christos   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
    303      1.1  christos   subargv[1] = "echo";
    304      1.1  christos   subargv[2] = "bar";
    305      1.1  christos   subargv[3] = NULL;
    306      1.1  christos   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
    307      1.1  christos   subargv[1] = "copy";
    308      1.1  christos   subargv[2] = NULL;
    309      1.1  christos   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
    310      1.1  christos   e = TEST_PEX_READ_OUTPUT (pex1);
    311      1.1  christos   CHECK_LINE (e, "bar");
    312      1.1  christos   TEST_PEX_GET_STATUS (pex1, 2, statuses);
    313      1.1  christos   if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
    314      1.1  christos       || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
    315      1.1  christos     ERROR ("copy exit status failed");
    316      1.1  christos   pex_free (pex1);
    317      1.1  christos   if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
    318      1.1  christos     ERROR ("temporary files exist");
    319      1.1  christos 
    320      1.1  christos   pex1 = TEST_PEX_INIT (0, "temp");
    321      1.1  christos   subargv[1] = "echo";
    322      1.1  christos   subargv[2] = "bar";
    323      1.1  christos   subargv[3] = NULL;
    324      1.1  christos   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
    325      1.1  christos   subargv[1] = "copy";
    326      1.1  christos   subargv[2] = NULL;
    327      1.1  christos   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
    328      1.1  christos   e = TEST_PEX_READ_OUTPUT (pex1);
    329      1.1  christos   CHECK_LINE (e, "bar");
    330      1.1  christos   TEST_PEX_GET_STATUS (pex1, 2, statuses);
    331      1.1  christos   if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
    332      1.1  christos       || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
    333      1.1  christos     ERROR ("copy exit status failed");
    334      1.1  christos   pex_free (pex1);
    335      1.1  christos   if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
    336      1.1  christos     ERROR ("temporary files exist");
    337      1.1  christos 
    338      1.1  christos   pex1 = TEST_PEX_INIT (PEX_SAVE_TEMPS, "temp");
    339      1.1  christos   subargv[1] = "echo";
    340      1.1  christos   subargv[2] = "quux";
    341      1.1  christos   subargv[3] = NULL;
    342      1.1  christos   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
    343      1.1  christos   subargv[1] = "copy";
    344      1.1  christos   subargv[2] = NULL;
    345      1.1  christos   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
    346      1.1  christos   e = TEST_PEX_READ_OUTPUT (pex1);
    347      1.1  christos   CHECK_LINE (e, "quux");
    348      1.1  christos   TEST_PEX_GET_STATUS (pex1, 2, statuses);
    349      1.1  christos   if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
    350      1.1  christos       || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
    351      1.1  christos     ERROR ("copy temp exit status failed");
    352      1.1  christos   e = fopen ("temp.x", "r");
    353      1.1  christos   if (e == NULL)
    354      1.1  christos     FATAL_ERROR ("fopen temp.x failed in copy temp", errno);
    355      1.1  christos   CHECK_LINE (e, "quux");
    356      1.1  christos   fclose (e);
    357      1.1  christos   e = fopen ("temp.y", "r");
    358      1.1  christos   if (e == NULL)
    359      1.1  christos     FATAL_ERROR ("fopen temp.y failed in copy temp", errno);
    360      1.1  christos   CHECK_LINE (e, "quux");
    361      1.1  christos   fclose (e);
    362      1.1  christos   pex_free (pex1);
    363      1.1  christos   remove ("temp.x");
    364      1.1  christos   remove ("temp.y");
    365      1.1  christos 
    366      1.1  christos   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
    367      1.1  christos   subargv[1] = "echoerr";
    368      1.1  christos   subargv[2] = "one";
    369      1.1  christos   subargv[3] = "two";
    370      1.1  christos   subargv[4] = NULL;
    371      1.1  christos   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", "temp2.x");
    372      1.1  christos   subargv[1] = "write";
    373      1.1  christos   subargv[2] = "temp2.y";
    374      1.1  christos   subargv[3] = NULL;
    375      1.1  christos   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
    376      1.1  christos   TEST_PEX_GET_STATUS (pex1, 2, statuses);
    377      1.1  christos   if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
    378      1.1  christos       || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
    379      1.1  christos     ERROR ("echoerr exit status failed");
    380      1.1  christos   pex_free (pex1);
    381      1.1  christos   if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
    382      1.1  christos     ERROR ("temporary files exist");
    383      1.1  christos   e = fopen ("temp2.x", "r");
    384      1.1  christos   if (e == NULL)
    385      1.1  christos     FATAL_ERROR ("fopen temp2.x failed in echoerr", errno);
    386      1.1  christos   CHECK_LINE (e, "two");
    387      1.1  christos   fclose (e);
    388      1.1  christos   e = fopen ("temp2.y", "r");
    389      1.1  christos   if (e == NULL)
    390      1.1  christos     FATAL_ERROR ("fopen temp2.y failed in echoerr", errno);
    391      1.1  christos   CHECK_LINE (e, "one");
    392      1.1  christos   fclose (e);
    393      1.1  christos   remove ("temp2.x");
    394      1.1  christos   remove ("temp2.y");
    395      1.1  christos 
    396      1.1  christos   /* Test the old pexecute interface.  */
    397      1.1  christos   {
    398      1.1  christos     int pid1, pid2;
    399      1.1  christos     char *errmsg_fmt;
    400      1.1  christos     char *errmsg_arg;
    401      1.1  christos     char errbuf1[1000];
    402      1.1  christos     char errbuf2[1000];
    403      1.1  christos 
    404      1.1  christos     subargv[1] = "echo";
    405      1.1  christos     subargv[2] = "oldpexecute";
    406      1.1  christos     subargv[3] = NULL;
    407      1.1  christos     pid1 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp",
    408      1.1  christos 		     &errmsg_fmt, &errmsg_arg, PEXECUTE_FIRST);
    409      1.1  christos     if (pid1 < 0)
    410      1.1  christos       {
    411      1.1  christos 	snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg);
    412      1.1  christos 	snprintf (errbuf2, sizeof errbuf2, "pexecute 1 failed: %s", errbuf1);
    413      1.1  christos 	FATAL_ERROR (errbuf2, 0);
    414      1.1  christos       }
    415      1.1  christos 
    416      1.1  christos     subargv[1] = "write";
    417      1.1  christos     subargv[2] = "temp.y";
    418      1.1  christos     subargv[3] = NULL;
    419      1.1  christos     pid2 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp",
    420      1.1  christos 		     &errmsg_fmt, &errmsg_arg, PEXECUTE_LAST);
    421      1.1  christos     if (pid2 < 0)
    422      1.1  christos       {
    423      1.1  christos 	snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg);
    424      1.1  christos 	snprintf (errbuf2, sizeof errbuf2, "pexecute 2 failed: %s", errbuf1);
    425      1.1  christos 	FATAL_ERROR (errbuf2, 0);
    426      1.1  christos       }
    427      1.1  christos 
    428      1.1  christos     if (pwait (pid1, &status, 0) < 0)
    429      1.1  christos       FATAL_ERROR ("write pwait 1 failed", errno);
    430      1.1  christos     if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
    431      1.1  christos       ERROR ("write exit status 1 failed");
    432      1.1  christos 
    433      1.1  christos     if (pwait (pid2, &status, 0) < 0)
    434      1.1  christos       FATAL_ERROR ("write pwait 1 failed", errno);
    435      1.1  christos     if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
    436      1.1  christos       ERROR ("write exit status 2 failed");
    437      1.1  christos 
    438      1.1  christos     e = fopen ("temp.y", "r");
    439      1.1  christos     if (e == NULL)
    440      1.1  christos       FATAL_ERROR ("fopen temp.y failed in copy temp", errno);
    441      1.1  christos     CHECK_LINE (e, "oldpexecute");
    442      1.1  christos     fclose (e);
    443      1.1  christos 
    444      1.1  christos     remove ("temp.y");
    445      1.1  christos   }
    446      1.1  christos 
    447      1.1  christos   if (trace)
    448      1.1  christos     fprintf (stderr, "Exiting with status %d\n", error_count);
    449      1.1  christos 
    450      1.1  christos   return error_count;
    451      1.1  christos }
    452      1.1  christos 
    453      1.1  christos /* Execute one of the special testing commands.  */
    454      1.1  christos 
    455      1.1  christos static void
    456      1.1  christos do_cmd (int argc, char **argv)
    457      1.1  christos {
    458      1.1  christos   const char *s;
    459      1.1  christos 
    460      1.1  christos   /* Try to prevent generating a core dump.  */
    461      1.1  christos #ifdef RLIMIT_CORE
    462      1.1  christos  {
    463      1.1  christos    struct rlimit r;
    464      1.1  christos 
    465      1.1  christos    r.rlim_cur = 0;
    466      1.1  christos    r.rlim_max = 0;
    467      1.1  christos    setrlimit (RLIMIT_CORE, &r);
    468      1.1  christos  }
    469      1.1  christos #endif
    470      1.1  christos 
    471      1.1  christos   s = argv[1];
    472      1.1  christos   if (strcmp (s, "exit") == 0)
    473      1.1  christos     exit (EXIT_SUCCESS);
    474      1.1  christos   else if (strcmp (s, "echo") == 0)
    475      1.1  christos     {
    476      1.1  christos       int i;
    477      1.1  christos 
    478      1.1  christos       for (i = 2; i < argc; ++i)
    479      1.1  christos 	{
    480      1.1  christos 	  if (i > 2)
    481      1.1  christos 	    putchar (' ');
    482      1.1  christos 	  fputs (argv[i], stdout);
    483      1.1  christos 	}
    484      1.1  christos       putchar ('\n');
    485      1.1  christos       exit (EXIT_SUCCESS);
    486      1.1  christos     }
    487      1.1  christos   else if (strcmp (s, "echoerr") == 0)
    488      1.1  christos     {
    489      1.1  christos       int i;
    490      1.1  christos 
    491      1.1  christos       for (i = 2; i < argc; ++i)
    492      1.1  christos 	{
    493      1.1  christos 	  if (i > 3)
    494      1.1  christos 	    putc (' ', (i & 1) == 0 ? stdout : stderr);
    495      1.1  christos 	  fputs (argv[i], (i & 1) == 0 ? stdout : stderr);
    496      1.1  christos 	}
    497      1.1  christos       putc ('\n', stdout);
    498      1.1  christos       putc ('\n', stderr);
    499      1.1  christos       exit (EXIT_SUCCESS);
    500      1.1  christos     }
    501      1.1  christos   else if (strcmp (s, "error") == 0)
    502      1.1  christos     exit (EXIT_FAILURE);
    503      1.1  christos   else if (strcmp (s, "abort") == 0)
    504      1.1  christos     abort ();
    505      1.1  christos   else if (strcmp (s, "copy") == 0)
    506      1.1  christos     {
    507      1.1  christos       int c;
    508      1.1  christos 
    509      1.1  christos       while ((c = getchar ()) != EOF)
    510      1.1  christos 	putchar (c);
    511      1.1  christos       exit (EXIT_SUCCESS);
    512      1.1  christos     }
    513      1.1  christos   else if (strcmp (s, "write") == 0)
    514      1.1  christos     {
    515      1.1  christos       FILE *e;
    516      1.1  christos       int c;
    517      1.1  christos 
    518      1.1  christos       e = fopen (argv[2], "w");
    519      1.1  christos       if (e == NULL)
    520      1.1  christos 	FATAL_ERROR ("fopen for write failed", errno);
    521      1.1  christos       while ((c = getchar ()) != EOF)
    522      1.1  christos 	putc (c, e);
    523      1.1  christos       if (fclose (e) != 0)
    524      1.1  christos 	FATAL_ERROR ("fclose for write failed", errno);
    525      1.1  christos       exit (EXIT_SUCCESS);
    526      1.1  christos     }
    527      1.1  christos   else
    528      1.1  christos     {
    529      1.1  christos       char buf[1000];
    530      1.1  christos 
    531      1.1  christos       snprintf (buf, sizeof buf, "unrecognized command %s", argv[1]);
    532      1.1  christos       FATAL_ERROR (buf, 0);
    533      1.1  christos     }
    534      1.1  christos 
    535      1.1  christos   exit (EXIT_FAILURE);
    536      1.1  christos }
    537