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