xref: /openbsd-src/gnu/lib/libiberty/src/testsuite/test-pexecute.c (revision 0fb20bf6d6cddd6a78c1d4d7a1d63e7277f390f8)
120fce977Smiod /* Pexecute test program,
220fce977Smiod    Copyright (C) 2005 Free Software Foundation, Inc.
320fce977Smiod    Written by Ian Lance Taylor <ian@airs.com>.
420fce977Smiod 
520fce977Smiod    This file is part of GNU libiberty.
620fce977Smiod 
720fce977Smiod    This program is free software; you can redistribute it and/or modify
820fce977Smiod    it under the terms of the GNU General Public License as published by
920fce977Smiod    the Free Software Foundation; either version 2 of the License, or
1020fce977Smiod    (at your option) any later version.
1120fce977Smiod 
1220fce977Smiod    This program is distributed in the hope that it will be useful,
1320fce977Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
1420fce977Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1520fce977Smiod    GNU General Public License for more details.
1620fce977Smiod 
1720fce977Smiod    You should have received a copy of the GNU General Public License
1820fce977Smiod    along with this program; if not, write to the Free Software
1920fce977Smiod    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2020fce977Smiod */
2120fce977Smiod 
2220fce977Smiod #ifdef HAVE_CONFIG_H
2320fce977Smiod #include "config.h"
2420fce977Smiod #endif
2520fce977Smiod #include "ansidecl.h"
2620fce977Smiod #include "libiberty.h"
2720fce977Smiod #include <stdio.h>
2820fce977Smiod #include <signal.h>
2920fce977Smiod #include <errno.h>
3020fce977Smiod #include <string.h>
3120fce977Smiod #include <sys/types.h>
3220fce977Smiod #include <stdlib.h>
3320fce977Smiod #include <unistd.h>
3420fce977Smiod #include <sys/wait.h>
3520fce977Smiod #include <sys/time.h>
3620fce977Smiod #include <sys/resource.h>
37*0fb20bf6Sbluhm 
38*0fb20bf6Sbluhm extern const char *pex_run (struct pex_obj *obj, int flags,
39*0fb20bf6Sbluhm                             const char *executable, char * const *argv,
40*0fb20bf6Sbluhm                             const char *outname, const char *errname,
41*0fb20bf6Sbluhm                             int *err);
42*0fb20bf6Sbluhm extern FILE *pex_read_output (struct pex_obj *, int binary);
43*0fb20bf6Sbluhm extern int pex_get_status (struct pex_obj *, int count, int *vector);
44*0fb20bf6Sbluhm extern void pex_free (struct pex_obj *);
4520fce977Smiod 
4620fce977Smiod #ifndef WIFSIGNALED
4720fce977Smiod #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
4820fce977Smiod #endif
4920fce977Smiod #ifndef WTERMSIG
5020fce977Smiod #define WTERMSIG(S) ((S) & 0x7f)
5120fce977Smiod #endif
5220fce977Smiod #ifndef WIFEXITED
5320fce977Smiod #define WIFEXITED(S) (((S) & 0xff) == 0)
5420fce977Smiod #endif
5520fce977Smiod #ifndef WEXITSTATUS
5620fce977Smiod #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
5720fce977Smiod #endif
5820fce977Smiod #ifndef WSTOPSIG
5920fce977Smiod #define WSTOPSIG WEXITSTATUS
6020fce977Smiod #endif
6120fce977Smiod #ifndef WCOREDUMP
6220fce977Smiod #define WCOREDUMP(S) ((S) & WCOREFLG)
6320fce977Smiod #endif
6420fce977Smiod #ifndef WCOREFLG
6520fce977Smiod #define WCOREFLG 0200
6620fce977Smiod #endif
6720fce977Smiod 
6820fce977Smiod #ifndef EXIT_SUCCESS
6920fce977Smiod #define EXIT_SUCCESS 0
7020fce977Smiod #endif
7120fce977Smiod 
7220fce977Smiod #ifndef EXIT_FAILURE
7320fce977Smiod #define EXIT_FAILURE 1
7420fce977Smiod #endif
7520fce977Smiod 
7620fce977Smiod /* When this program is run with no arguments, it runs some tests of
7720fce977Smiod    the libiberty pexecute functions.  As a test program, it simply
7820fce977Smiod    invokes itself with various arguments.
7920fce977Smiod 
8020fce977Smiod    argv[1]:
8120fce977Smiod      *empty string*      Run tests, exit with success status
8220fce977Smiod      exit                Exit success
8320fce977Smiod      error               Exit error
8420fce977Smiod      abort               Abort
8520fce977Smiod      echo                Echo remaining arguments, exit success
8620fce977Smiod      echoerr             Echo next arg to stdout, next to stderr, repeat
8720fce977Smiod      copy                Copy stdin to stdout
8820fce977Smiod      write               Write stdin to file named in next argument
8920fce977Smiod */
9020fce977Smiod 
9120fce977Smiod static void fatal_error (int, const char *, int) ATTRIBUTE_NORETURN;
9220fce977Smiod static void error (int, const char *);
9320fce977Smiod static void check_line (int, FILE *, const char *);
9420fce977Smiod static void do_cmd (int, char **) ATTRIBUTE_NORETURN;
9520fce977Smiod 
9620fce977Smiod /* The number of errors we have seen.  */
9720fce977Smiod 
9820fce977Smiod static int error_count;
9920fce977Smiod 
10020fce977Smiod /* Print a fatal error and exit.  LINE is the line number where we
10120fce977Smiod    detected the error, ERRMSG is the error message to print, and ERR
10220fce977Smiod    is 0 or an errno value to print.  */
10320fce977Smiod 
10420fce977Smiod static void
fatal_error(int line,const char * errmsg,int err)10520fce977Smiod fatal_error (int line, const char *errmsg, int err)
10620fce977Smiod {
10720fce977Smiod   fprintf (stderr, "test-pexecute:%d: %s", line, errmsg);
10820fce977Smiod   if (errno != 0)
10920fce977Smiod     fprintf (stderr, ": %s", xstrerror (err));
11020fce977Smiod   fprintf (stderr, "\n");
11120fce977Smiod   exit (EXIT_FAILURE);
11220fce977Smiod }
11320fce977Smiod 
11420fce977Smiod #define FATAL_ERROR(ERRMSG, ERR) fatal_error (__LINE__, ERRMSG, ERR)
11520fce977Smiod 
11620fce977Smiod /* Print an error message and bump the error count.  LINE is the line
11720fce977Smiod    number where we detected the error, ERRMSG is the error to
11820fce977Smiod    print.  */
11920fce977Smiod 
12020fce977Smiod static void
error(int line,const char * errmsg)12120fce977Smiod error (int line, const char *errmsg)
12220fce977Smiod {
12320fce977Smiod   fprintf (stderr, "test-pexecute:%d: %s\n", line, errmsg);
12420fce977Smiod   ++error_count;
12520fce977Smiod }
12620fce977Smiod 
12720fce977Smiod #define ERROR(ERRMSG) error (__LINE__, ERRMSG)
12820fce977Smiod 
12920fce977Smiod /* Check a line in a file.  */
13020fce977Smiod 
13120fce977Smiod static void
check_line(int line,FILE * e,const char * str)13220fce977Smiod check_line (int line, FILE *e, const char *str)
13320fce977Smiod {
13420fce977Smiod   const char *p;
13520fce977Smiod   int c;
13620fce977Smiod   char buf[1000];
13720fce977Smiod 
13820fce977Smiod   p = str;
13920fce977Smiod   while (1)
14020fce977Smiod     {
14120fce977Smiod       c = getc (e);
14220fce977Smiod 
14320fce977Smiod       if (*p == '\0')
14420fce977Smiod 	{
14520fce977Smiod 	  if (c != '\n')
14620fce977Smiod 	    {
14720fce977Smiod 	      snprintf (buf, sizeof buf, "got '%c' when expecting newline", c);
14820fce977Smiod 	      fatal_error (line, buf, 0);
14920fce977Smiod 	    }
15020fce977Smiod 	  c = getc (e);
15120fce977Smiod 	  if (c != EOF)
15220fce977Smiod 	    {
15320fce977Smiod 	      snprintf (buf, sizeof buf, "got '%c' when expecting EOF", c);
15420fce977Smiod 	      fatal_error (line, buf, 0);
15520fce977Smiod 	    }
15620fce977Smiod 	  return;
15720fce977Smiod 	}
15820fce977Smiod 
15920fce977Smiod       if (c != *p)
16020fce977Smiod 	{
16120fce977Smiod 	  snprintf (buf, sizeof buf, "expected '%c', got '%c'", *p, c);
16220fce977Smiod 	  fatal_error (line, buf, 0);
16320fce977Smiod 	}
16420fce977Smiod 
16520fce977Smiod       ++p;
16620fce977Smiod     }
16720fce977Smiod }
16820fce977Smiod 
16920fce977Smiod #define CHECK_LINE(E, STR) check_line (__LINE__, E, STR)
17020fce977Smiod 
17120fce977Smiod /* Main function for the pexecute tester.  Run the tests.  */
17220fce977Smiod 
17320fce977Smiod int
main(int argc,char ** argv)17420fce977Smiod main (int argc, char **argv)
17520fce977Smiod {
17620fce977Smiod   int trace;
17720fce977Smiod   struct pex_obj *test_pex_tmp;
17820fce977Smiod   int test_pex_status;
17920fce977Smiod   FILE *test_pex_file;
18020fce977Smiod   struct pex_obj *pex1;
18120fce977Smiod   char *subargv[10];
18220fce977Smiod   int status;
18320fce977Smiod   FILE *e;
18420fce977Smiod   int statuses[10];
18520fce977Smiod 
18620fce977Smiod   trace = 0;
18720fce977Smiod   if (argc > 1 && strcmp (argv[1], "-t") == 0)
18820fce977Smiod     {
18920fce977Smiod       trace = 1;
19020fce977Smiod       --argc;
19120fce977Smiod       ++argv;
19220fce977Smiod     }
19320fce977Smiod 
19420fce977Smiod   if (argc > 1)
19520fce977Smiod     do_cmd (argc, argv);
19620fce977Smiod 
19720fce977Smiod #define TEST_PEX_INIT(FLAGS, TEMPBASE)					\
19820fce977Smiod   (((test_pex_tmp = pex_init (FLAGS, "test-pexecute", TEMPBASE))	\
19920fce977Smiod     != NULL)								\
20020fce977Smiod    ? test_pex_tmp							\
20120fce977Smiod    : (FATAL_ERROR ("pex_init failed", 0), NULL))
20220fce977Smiod 
20320fce977Smiod #define TEST_PEX_RUN(PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME, ERRNAME)	\
20420fce977Smiod   do									\
20520fce977Smiod     {									\
20620fce977Smiod       int err;								\
20720fce977Smiod       const char *pex_run_err;						\
20820fce977Smiod       if (trace)							\
20920fce977Smiod 	fprintf (stderr, "Line %d: running %s %s\n",			\
21020fce977Smiod 		 __LINE__, EXECUTABLE, ARGV[0]);			\
21120fce977Smiod       pex_run_err = pex_run (PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME,	\
21220fce977Smiod 			     ERRNAME, &err);				\
21320fce977Smiod       if (pex_run_err != NULL)						\
21420fce977Smiod 	FATAL_ERROR (pex_run_err, err);					\
21520fce977Smiod     }									\
21620fce977Smiod   while (0)
21720fce977Smiod 
21820fce977Smiod #define TEST_PEX_GET_STATUS_1(PEXOBJ)					\
21920fce977Smiod   (pex_get_status (PEXOBJ, 1, &test_pex_status)				\
22020fce977Smiod    ? test_pex_status							\
22120fce977Smiod    : (FATAL_ERROR ("pex_get_status failed", errno), 1))
22220fce977Smiod 
22320fce977Smiod #define TEST_PEX_GET_STATUS(PEXOBJ, COUNT, VECTOR)			\
22420fce977Smiod   do									\
22520fce977Smiod     {									\
22620fce977Smiod       if (!pex_get_status (PEXOBJ, COUNT, VECTOR))			\
22720fce977Smiod 	FATAL_ERROR ("pex_get_status failed", errno);			\
22820fce977Smiod     }									\
22920fce977Smiod   while (0)
23020fce977Smiod 
23120fce977Smiod #define TEST_PEX_READ_OUTPUT(PEXOBJ)					\
23220fce977Smiod   ((test_pex_file = pex_read_output (PEXOBJ, 0)) != NULL		\
23320fce977Smiod    ? test_pex_file							\
23420fce977Smiod    : (FATAL_ERROR ("pex_read_output failed", errno), NULL))
23520fce977Smiod 
23620fce977Smiod   remove ("temp.x");
23720fce977Smiod   remove ("temp.y");
23820fce977Smiod 
23920fce977Smiod   memset (subargv, 0, sizeof subargv);
24020fce977Smiod 
24120fce977Smiod   subargv[0] = "./test-pexecute";
24220fce977Smiod 
24320fce977Smiod   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
24420fce977Smiod   subargv[1] = "exit";
24520fce977Smiod   subargv[2] = NULL;
24620fce977Smiod   TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL);
24720fce977Smiod   status = TEST_PEX_GET_STATUS_1 (pex1);
24820fce977Smiod   if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
24920fce977Smiod     ERROR ("exit failed");
25020fce977Smiod   pex_free (pex1);
25120fce977Smiod 
25220fce977Smiod   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
25320fce977Smiod   subargv[1] = "error";
25420fce977Smiod   subargv[2] = NULL;
25520fce977Smiod   TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL);
25620fce977Smiod   status = TEST_PEX_GET_STATUS_1 (pex1);
25720fce977Smiod   if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_FAILURE)
25820fce977Smiod     ERROR ("error test failed");
25920fce977Smiod   pex_free (pex1);
26020fce977Smiod 
26120fce977Smiod   /* We redirect stderr to a file to avoid an error message which is
26220fce977Smiod      printed on mingw32 when the child calls abort.  */
26320fce977Smiod   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
26420fce977Smiod   subargv[1] = "abort";
26520fce977Smiod   subargv[2] = NULL;
26620fce977Smiod   TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, "temp.z");
26720fce977Smiod   status = TEST_PEX_GET_STATUS_1 (pex1);
26820fce977Smiod   if (!WIFSIGNALED (status) || WTERMSIG (status) != SIGABRT)
26920fce977Smiod     ERROR ("abort failed");
27020fce977Smiod   pex_free (pex1);
27120fce977Smiod   remove ("temp.z");
27220fce977Smiod 
27320fce977Smiod   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
27420fce977Smiod   subargv[1] = "echo";
27520fce977Smiod   subargv[2] = "foo";
27620fce977Smiod   subargv[3] = NULL;
27720fce977Smiod   TEST_PEX_RUN (pex1, 0, "./test-pexecute", subargv, NULL, NULL);
27820fce977Smiod   e = TEST_PEX_READ_OUTPUT (pex1);
27920fce977Smiod   CHECK_LINE (e, "foo");
28020fce977Smiod   if (TEST_PEX_GET_STATUS_1 (pex1) != 0)
28120fce977Smiod     ERROR ("echo exit status failed");
28220fce977Smiod   pex_free (pex1);
28320fce977Smiod 
28420fce977Smiod   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
28520fce977Smiod   subargv[1] = "echo";
28620fce977Smiod   subargv[2] = "bar";
28720fce977Smiod   subargv[3] = NULL;
28820fce977Smiod   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
28920fce977Smiod   subargv[1] = "copy";
29020fce977Smiod   subargv[2] = NULL;
29120fce977Smiod   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
29220fce977Smiod   e = TEST_PEX_READ_OUTPUT (pex1);
29320fce977Smiod   CHECK_LINE (e, "bar");
29420fce977Smiod   TEST_PEX_GET_STATUS (pex1, 2, statuses);
29520fce977Smiod   if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
29620fce977Smiod       || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
29720fce977Smiod     ERROR ("copy exit status failed");
29820fce977Smiod   pex_free (pex1);
29920fce977Smiod   if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
30020fce977Smiod     ERROR ("temporary files exist");
30120fce977Smiod 
30220fce977Smiod   pex1 = TEST_PEX_INIT (0, "temp");
30320fce977Smiod   subargv[1] = "echo";
30420fce977Smiod   subargv[2] = "bar";
30520fce977Smiod   subargv[3] = NULL;
30620fce977Smiod   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
30720fce977Smiod   subargv[1] = "copy";
30820fce977Smiod   subargv[2] = NULL;
30920fce977Smiod   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
31020fce977Smiod   e = TEST_PEX_READ_OUTPUT (pex1);
31120fce977Smiod   CHECK_LINE (e, "bar");
31220fce977Smiod   TEST_PEX_GET_STATUS (pex1, 2, statuses);
31320fce977Smiod   if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
31420fce977Smiod       || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
31520fce977Smiod     ERROR ("copy exit status failed");
31620fce977Smiod   pex_free (pex1);
31720fce977Smiod   if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
31820fce977Smiod     ERROR ("temporary files exist");
31920fce977Smiod 
32020fce977Smiod   pex1 = TEST_PEX_INIT (PEX_SAVE_TEMPS, "temp");
32120fce977Smiod   subargv[1] = "echo";
32220fce977Smiod   subargv[2] = "quux";
32320fce977Smiod   subargv[3] = NULL;
32420fce977Smiod   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
32520fce977Smiod   subargv[1] = "copy";
32620fce977Smiod   subargv[2] = NULL;
32720fce977Smiod   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
32820fce977Smiod   e = TEST_PEX_READ_OUTPUT (pex1);
32920fce977Smiod   CHECK_LINE (e, "quux");
33020fce977Smiod   TEST_PEX_GET_STATUS (pex1, 2, statuses);
33120fce977Smiod   if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
33220fce977Smiod       || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
33320fce977Smiod     ERROR ("copy temp exit status failed");
33420fce977Smiod   e = fopen ("temp.x", "r");
33520fce977Smiod   if (e == NULL)
33620fce977Smiod     FATAL_ERROR ("fopen temp.x failed in copy temp", errno);
33720fce977Smiod   CHECK_LINE (e, "quux");
33820fce977Smiod   fclose (e);
33920fce977Smiod   e = fopen ("temp.y", "r");
34020fce977Smiod   if (e == NULL)
34120fce977Smiod     FATAL_ERROR ("fopen temp.y failed in copy temp", errno);
34220fce977Smiod   CHECK_LINE (e, "quux");
34320fce977Smiod   fclose (e);
34420fce977Smiod   pex_free (pex1);
34520fce977Smiod   remove ("temp.x");
34620fce977Smiod   remove ("temp.y");
34720fce977Smiod 
34820fce977Smiod   pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
34920fce977Smiod   subargv[1] = "echoerr";
35020fce977Smiod   subargv[2] = "one";
35120fce977Smiod   subargv[3] = "two";
35220fce977Smiod   subargv[4] = NULL;
35320fce977Smiod   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", "temp2.x");
35420fce977Smiod   subargv[1] = "write";
35520fce977Smiod   subargv[2] = "temp2.y";
35620fce977Smiod   subargv[3] = NULL;
35720fce977Smiod   TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
35820fce977Smiod   TEST_PEX_GET_STATUS (pex1, 2, statuses);
35920fce977Smiod   if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
36020fce977Smiod       || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
36120fce977Smiod     ERROR ("echoerr exit status failed");
36220fce977Smiod   pex_free (pex1);
36320fce977Smiod   if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
36420fce977Smiod     ERROR ("temporary files exist");
36520fce977Smiod   e = fopen ("temp2.x", "r");
36620fce977Smiod   if (e == NULL)
36720fce977Smiod     FATAL_ERROR ("fopen temp2.x failed in echoerr", errno);
36820fce977Smiod   CHECK_LINE (e, "two");
36920fce977Smiod   fclose (e);
37020fce977Smiod   e = fopen ("temp2.y", "r");
37120fce977Smiod   if (e == NULL)
37220fce977Smiod     FATAL_ERROR ("fopen temp2.y failed in echoerr", errno);
37320fce977Smiod   CHECK_LINE (e, "one");
37420fce977Smiod   fclose (e);
37520fce977Smiod   remove ("temp2.x");
37620fce977Smiod   remove ("temp2.y");
37720fce977Smiod 
37820fce977Smiod   /* Test the old pexecute interface.  */
37920fce977Smiod   {
38020fce977Smiod     int pid1, pid2;
38120fce977Smiod     char *errmsg_fmt;
38220fce977Smiod     char *errmsg_arg;
38320fce977Smiod     char errbuf1[1000];
38420fce977Smiod     char errbuf2[1000];
38520fce977Smiod 
38620fce977Smiod     subargv[1] = "echo";
38720fce977Smiod     subargv[2] = "oldpexecute";
38820fce977Smiod     subargv[3] = NULL;
38920fce977Smiod     pid1 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp",
39020fce977Smiod 		     &errmsg_fmt, &errmsg_arg, PEXECUTE_FIRST);
39120fce977Smiod     if (pid1 < 0)
39220fce977Smiod       {
39320fce977Smiod 	snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg);
39420fce977Smiod 	snprintf (errbuf2, sizeof errbuf2, "pexecute 1 failed: %s", errbuf1);
39520fce977Smiod 	FATAL_ERROR (errbuf2, 0);
39620fce977Smiod       }
39720fce977Smiod 
39820fce977Smiod     subargv[1] = "write";
39920fce977Smiod     subargv[2] = "temp.y";
40020fce977Smiod     subargv[3] = NULL;
40120fce977Smiod     pid2 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp",
40220fce977Smiod 		     &errmsg_fmt, &errmsg_arg, PEXECUTE_LAST);
40320fce977Smiod     if (pid2 < 0)
40420fce977Smiod       {
40520fce977Smiod 	snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg);
40620fce977Smiod 	snprintf (errbuf2, sizeof errbuf2, "pexecute 2 failed: %s", errbuf1);
40720fce977Smiod 	FATAL_ERROR (errbuf2, 0);
40820fce977Smiod       }
40920fce977Smiod 
41020fce977Smiod     if (pwait (pid1, &status, 0) < 0)
41120fce977Smiod       FATAL_ERROR ("write pwait 1 failed", errno);
41220fce977Smiod     if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
41320fce977Smiod       ERROR ("write exit status 1 failed");
41420fce977Smiod 
41520fce977Smiod     if (pwait (pid2, &status, 0) < 0)
41620fce977Smiod       FATAL_ERROR ("write pwait 1 failed", errno);
41720fce977Smiod     if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
41820fce977Smiod       ERROR ("write exit status 2 failed");
41920fce977Smiod 
42020fce977Smiod     e = fopen ("temp.y", "r");
42120fce977Smiod     if (e == NULL)
42220fce977Smiod       FATAL_ERROR ("fopen temp.y failed in copy temp", errno);
42320fce977Smiod     CHECK_LINE (e, "oldpexecute");
42420fce977Smiod     fclose (e);
42520fce977Smiod 
42620fce977Smiod     remove ("temp.y");
42720fce977Smiod   }
42820fce977Smiod 
42920fce977Smiod   if (trace)
43020fce977Smiod     fprintf (stderr, "Exiting with status %d\n", error_count);
43120fce977Smiod 
43220fce977Smiod   return error_count;
43320fce977Smiod }
43420fce977Smiod 
43520fce977Smiod /* Execute one of the special testing commands.  */
43620fce977Smiod 
43720fce977Smiod static void
do_cmd(int argc,char ** argv)43820fce977Smiod do_cmd (int argc, char **argv)
43920fce977Smiod {
44020fce977Smiod   const char *s;
44120fce977Smiod 
44220fce977Smiod   /* Try to prevent generating a core dump.  */
44320fce977Smiod #ifdef RLIMIT_CORE
44420fce977Smiod  {
44520fce977Smiod    struct rlimit r;
44620fce977Smiod 
44720fce977Smiod    r.rlim_cur = 0;
44820fce977Smiod    r.rlim_max = 0;
44920fce977Smiod    setrlimit (RLIMIT_CORE, &r);
45020fce977Smiod  }
45120fce977Smiod #endif
45220fce977Smiod 
45320fce977Smiod   s = argv[1];
45420fce977Smiod   if (strcmp (s, "exit") == 0)
45520fce977Smiod     exit (EXIT_SUCCESS);
45620fce977Smiod   else if (strcmp (s, "echo") == 0)
45720fce977Smiod     {
45820fce977Smiod       int i;
45920fce977Smiod 
46020fce977Smiod       for (i = 2; i < argc; ++i)
46120fce977Smiod 	{
46220fce977Smiod 	  if (i > 2)
46320fce977Smiod 	    putchar (' ');
46420fce977Smiod 	  fputs (argv[i], stdout);
46520fce977Smiod 	}
46620fce977Smiod       putchar ('\n');
46720fce977Smiod       exit (EXIT_SUCCESS);
46820fce977Smiod     }
46920fce977Smiod   else if (strcmp (s, "echoerr") == 0)
47020fce977Smiod     {
47120fce977Smiod       int i;
47220fce977Smiod 
47320fce977Smiod       for (i = 2; i < argc; ++i)
47420fce977Smiod 	{
47520fce977Smiod 	  if (i > 3)
47620fce977Smiod 	    putc (' ', (i & 1) == 0 ? stdout : stderr);
47720fce977Smiod 	  fputs (argv[i], (i & 1) == 0 ? stdout : stderr);
47820fce977Smiod 	}
47920fce977Smiod       putc ('\n', stdout);
48020fce977Smiod       putc ('\n', stderr);
48120fce977Smiod       exit (EXIT_SUCCESS);
48220fce977Smiod     }
48320fce977Smiod   else if (strcmp (s, "error") == 0)
48420fce977Smiod     exit (EXIT_FAILURE);
48520fce977Smiod   else if (strcmp (s, "abort") == 0)
48620fce977Smiod     abort ();
48720fce977Smiod   else if (strcmp (s, "copy") == 0)
48820fce977Smiod     {
48920fce977Smiod       int c;
49020fce977Smiod 
49120fce977Smiod       while ((c = getchar ()) != EOF)
49220fce977Smiod 	putchar (c);
49320fce977Smiod       exit (EXIT_SUCCESS);
49420fce977Smiod     }
49520fce977Smiod   else if (strcmp (s, "write") == 0)
49620fce977Smiod     {
49720fce977Smiod       FILE *e;
49820fce977Smiod       int c;
49920fce977Smiod 
50020fce977Smiod       e = fopen (argv[2], "w");
50120fce977Smiod       if (e == NULL)
50220fce977Smiod 	FATAL_ERROR ("fopen for write failed", errno);
50320fce977Smiod       while ((c = getchar ()) != EOF)
50420fce977Smiod 	putc (c, e);
50520fce977Smiod       if (fclose (e) != 0)
50620fce977Smiod 	FATAL_ERROR ("fclose for write failed", errno);
50720fce977Smiod       exit (EXIT_SUCCESS);
50820fce977Smiod     }
50920fce977Smiod   else
51020fce977Smiod     {
51120fce977Smiod       char buf[1000];
51220fce977Smiod 
51320fce977Smiod       snprintf (buf, sizeof buf, "unrecognized command %s", argv[1]);
51420fce977Smiod       FATAL_ERROR (buf, 0);
51520fce977Smiod     }
51620fce977Smiod 
51720fce977Smiod   exit (EXIT_FAILURE);
51820fce977Smiod }
519